blob: 62b169036ea128bf8ba654bc7e8ff54ff548eac5 [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"
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001628
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001629 def test_add_extensions_wrong_args(self):
1630 """
Alex Chanb00ede22017-01-30 07:24:40 +00001631 `X509Req.add_extensions` raises `TypeError` if called with a
1632 non-`list`. Or it raises `ValueError` if called with a `list`
1633 containing objects other than `X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001634 """
1635 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001636 with pytest.raises(TypeError):
1637 request.add_extensions(object())
1638 with pytest.raises(ValueError):
1639 request.add_extensions([object()])
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001640
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001641 def test_verify_wrong_args(self):
1642 """
Alex Chanb00ede22017-01-30 07:24:40 +00001643 `X509Req.verify` raises `TypeError` if passed anything other than a
1644 `PKey` instance as its single argument.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001645 """
1646 request = X509Req()
Alex Chanb00ede22017-01-30 07:24:40 +00001647 with pytest.raises(TypeError):
1648 request.verify(object())
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001649
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001650 def test_verify_uninitialized_key(self):
1651 """
Alex Chanb00ede22017-01-30 07:24:40 +00001652 `X509Req.verify` raises `OpenSSL.crypto.Error` if called with a
1653 `OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001654 """
1655 request = X509Req()
1656 pkey = PKey()
Alex Chanb00ede22017-01-30 07:24:40 +00001657 with pytest.raises(Error):
1658 request.verify(pkey)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001659
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001660 def test_verify_wrong_key(self):
1661 """
Alex Chanb00ede22017-01-30 07:24:40 +00001662 `X509Req.verify` raises `OpenSSL.crypto.Error` if called with a
1663 `OpenSSL.crypto.PKey` which does not represent the public part of the
Alex Gaynor31287502015-09-05 16:11:27 -04001664 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001665 """
1666 request = X509Req()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001667 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001668 request.sign(pkey, GOOD_DIGEST)
Alex Chanb00ede22017-01-30 07:24:40 +00001669 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1670 with pytest.raises(Error):
1671 request.verify(another_pkey)
1672
1673 def test_verify_success(self):
1674 """
1675 `X509Req.verify` returns `True` if called with a `OpenSSL.crypto.PKey`
1676 which represents the public part of the key which signed the request.
1677 """
1678 request = X509Req()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001679 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001680 request.sign(pkey, GOOD_DIGEST)
1681 assert request.verify(pkey)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001682
Paul Kehrer41c10242017-06-29 18:24:17 -05001683 def test_convert_from_cryptography(self):
1684 crypto_req = x509.load_pem_x509_csr(
1685 cleartextCertificateRequestPEM, backend
1686 )
1687 req = X509Req.from_cryptography(crypto_req)
1688 assert isinstance(req, X509Req)
1689
1690 def test_convert_from_cryptography_unsupported_type(self):
1691 with pytest.raises(TypeError):
1692 X509Req.from_cryptography(object())
1693
1694 def test_convert_to_cryptography_key(self):
1695 req = load_certificate_request(
1696 FILETYPE_PEM, cleartextCertificateRequestPEM
1697 )
1698 crypto_req = req.to_cryptography()
1699 assert isinstance(crypto_req, x509.CertificateSigningRequest)
1700
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001701
Alex Chanb00ede22017-01-30 07:24:40 +00001702class TestX509(_PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001703 """
Alex Chanb00ede22017-01-30 07:24:40 +00001704 Tests for `OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001705 """
Alex Gaynor03737182020-07-23 20:40:46 -04001706
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05001707 pemData = root_cert_pem + root_key_pem
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001708
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001709 def signable(self):
1710 """
Alex Chanb00ede22017-01-30 07:24:40 +00001711 Create and return a new `X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001712 """
1713 return X509()
1714
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001715 def test_type(self):
1716 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001717 `X509` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001718 """
Alex Gaynor03737182020-07-23 20:40:46 -04001719 assert is_consistent_type(X509, "X509")
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001720
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001721 def test_construction(self):
1722 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05001723 `X509` takes no arguments and returns an instance of `X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001724 """
1725 certificate = X509()
Alex Gaynor01f90a12019-02-07 09:14:48 -05001726 assert isinstance(certificate, X509)
Alex Gaynor03737182020-07-23 20:40:46 -04001727 assert type(certificate).__name__ == "X509"
Alex Chanb00ede22017-01-30 07:24:40 +00001728 assert type(certificate) == X509
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001729
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001730 def test_set_version_wrong_args(self):
1731 """
Alex Chanb00ede22017-01-30 07:24:40 +00001732 `X509.set_version` raises `TypeError` if invoked with an argument
1733 not of type `int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001734 """
1735 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001736 with pytest.raises(TypeError):
1737 cert.set_version(None)
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001738
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001739 def test_version(self):
1740 """
Alex Chanb00ede22017-01-30 07:24:40 +00001741 `X509.set_version` sets the certificate version number.
1742 `X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001743 """
1744 cert = X509()
1745 cert.set_version(1234)
Alex Chanb00ede22017-01-30 07:24:40 +00001746 assert cert.get_version() == 1234
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001747
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001748 def test_serial_number(self):
1749 """
Alex Chanb00ede22017-01-30 07:24:40 +00001750 The serial number of an `X509` can be retrieved and
1751 modified with `X509.get_serial_number` and
1752 `X509.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001753 """
1754 certificate = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001755 with pytest.raises(TypeError):
1756 certificate.set_serial_number("1")
1757 assert certificate.get_serial_number() == 0
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001758 certificate.set_serial_number(1)
Alex Chanb00ede22017-01-30 07:24:40 +00001759 assert certificate.get_serial_number() == 1
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001760 certificate.set_serial_number(2 ** 32 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001761 assert certificate.get_serial_number() == 2 ** 32 + 1
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001762 certificate.set_serial_number(2 ** 64 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001763 assert certificate.get_serial_number() == 2 ** 64 + 1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001764 certificate.set_serial_number(2 ** 128 + 1)
Alex Chanb00ede22017-01-30 07:24:40 +00001765 assert certificate.get_serial_number() == 2 ** 128 + 1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001766
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001767 def _setBoundTest(self, which):
1768 """
Alex Chanb00ede22017-01-30 07:24:40 +00001769 `X509.set_notBefore` takes a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001770 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1771 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001772 """
1773 certificate = X509()
Alex Gaynor03737182020-07-23 20:40:46 -04001774 set = getattr(certificate, "set_not" + which)
1775 get = getattr(certificate, "get_not" + which)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001776
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001777 # Starts with no value.
Alex Chanb00ede22017-01-30 07:24:40 +00001778 assert get() is None
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001779
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001780 # GMT (Or is it UTC?) -exarkun
Alex Gaynore7f51982016-09-11 11:48:14 -04001781 when = b"20040203040506Z"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001782 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001783 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001784
1785 # A plus two hours and thirty minutes offset
Alex Gaynore7f51982016-09-11 11:48:14 -04001786 when = b"20040203040506+0530"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001787 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001788 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001789
1790 # A minus one hour fifteen minutes offset
Alex Gaynore7f51982016-09-11 11:48:14 -04001791 when = b"20040203040506-0115"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001792 set(when)
Alex Chanb00ede22017-01-30 07:24:40 +00001793 assert get() == when
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001794
1795 # An invalid string results in a ValueError
Alex Chanb00ede22017-01-30 07:24:40 +00001796 with pytest.raises(ValueError):
1797 set(b"foo bar")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001798
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001799 # The wrong number of arguments results in a TypeError.
Alex Chanb00ede22017-01-30 07:24:40 +00001800 with pytest.raises(TypeError):
1801 set()
Alex Gaynor85b49702015-09-05 16:30:59 -04001802 with pytest.raises(TypeError):
1803 set(b"20040203040506Z", b"20040203040506Z")
Alex Chanb00ede22017-01-30 07:24:40 +00001804 with pytest.raises(TypeError):
1805 get(b"foo bar")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001806
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001807 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001808
1809 def test_set_notBefore(self):
1810 """
Alex Chanb00ede22017-01-30 07:24:40 +00001811 `X509.set_notBefore` takes a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001812 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1813 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001814 """
1815 self._setBoundTest("Before")
1816
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001817 def test_set_notAfter(self):
1818 """
Alex Chanb00ede22017-01-30 07:24:40 +00001819 `X509.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001820 GENERALIZEDTIME and sets the end of the certificate's validity period
1821 to it.
1822 """
1823 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001824
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001825 def test_get_notBefore(self):
1826 """
Alex Chanb00ede22017-01-30 07:24:40 +00001827 `X509.get_notBefore` returns a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001828 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001829 internally.
1830 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001831 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001832 assert cert.get_notBefore() == b"20090325123658Z"
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001833
Rick Dean38a05c82009-07-18 01:41:30 -05001834 def test_get_notAfter(self):
1835 """
Alex Chanb00ede22017-01-30 07:24:40 +00001836 `X509.get_notAfter` returns a string in the format of an
Alex Gaynor31287502015-09-05 16:11:27 -04001837 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001838 internally.
1839 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001840 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001841 assert cert.get_notAfter() == b"20170611123658Z"
Rick Dean38a05c82009-07-18 01:41:30 -05001842
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001843 def test_gmtime_adj_notBefore_wrong_args(self):
1844 """
Alex Chanb00ede22017-01-30 07:24:40 +00001845 `X509.gmtime_adj_notBefore` raises `TypeError` if called with a
1846 non-`int` argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001847 """
1848 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001849 with pytest.raises(TypeError):
1850 cert.gmtime_adj_notBefore(None)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001851
Alex Gaynor7f5610c2017-07-07 00:09:34 -04001852 @flaky.flaky
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001853 def test_gmtime_adj_notBefore(self):
1854 """
Alex Chanb00ede22017-01-30 07:24:40 +00001855 `X509.gmtime_adj_notBefore` changes the not-before timestamp to be the
1856 current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001857 """
1858 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor03737182020-07-23 20:40:46 -04001859 not_before_min = datetime.utcnow().replace(microsecond=0) + timedelta(
1860 seconds=100
Alex Gaynor85b49702015-09-05 16:30:59 -04001861 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001862 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001863 not_before = datetime.strptime(
1864 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1865 )
Alex Gaynor7f5610c2017-07-07 00:09:34 -04001866 not_before_max = datetime.utcnow() + timedelta(seconds=100)
Alex Chanb00ede22017-01-30 07:24:40 +00001867 assert not_before_min <= not_before <= not_before_max
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001868
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001869 def test_gmtime_adj_notAfter_wrong_args(self):
1870 """
Alex Chanb00ede22017-01-30 07:24:40 +00001871 `X509.gmtime_adj_notAfter` raises `TypeError` if called with a
1872 non-`int` argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001873 """
1874 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00001875 with pytest.raises(TypeError):
1876 cert.gmtime_adj_notAfter(None)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001877
Alex Gaynor642de6f2017-07-24 00:57:38 -04001878 @flaky.flaky
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001879 def test_gmtime_adj_notAfter(self):
1880 """
Alex Chanb00ede22017-01-30 07:24:40 +00001881 `X509.gmtime_adj_notAfter` changes the not-after timestamp
Alex Gaynor31287502015-09-05 16:11:27 -04001882 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001883 """
1884 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor03737182020-07-23 20:40:46 -04001885 not_after_min = datetime.utcnow().replace(microsecond=0) + timedelta(
1886 seconds=100
Alex Gaynor85b49702015-09-05 16:30:59 -04001887 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001888 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001889 not_after = datetime.strptime(
1890 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1891 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001892 not_after_max = datetime.utcnow() + timedelta(seconds=100)
Alex Chanb00ede22017-01-30 07:24:40 +00001893 assert not_after_min <= not_after <= not_after_max
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001894
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001895 def test_has_expired(self):
1896 """
Alex Chanb00ede22017-01-30 07:24:40 +00001897 `X509.has_expired` returns `True` if the certificate's not-after time
1898 is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001899 """
1900 cert = X509()
1901 cert.gmtime_adj_notAfter(-1)
Alex Chanb00ede22017-01-30 07:24:40 +00001902 assert cert.has_expired()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001903
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001904 def test_has_not_expired(self):
1905 """
Alex Chanb00ede22017-01-30 07:24:40 +00001906 `X509.has_expired` returns `False` if the certificate's not-after time
1907 is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001908 """
1909 cert = X509()
1910 cert.gmtime_adj_notAfter(2)
Alex Chanb00ede22017-01-30 07:24:40 +00001911 assert not cert.has_expired()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001912
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001913 def test_root_has_not_expired(self):
1914 """
Alex Chanb00ede22017-01-30 07:24:40 +00001915 `X509.has_expired` returns `False` if the certificate's not-after time
1916 is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001917 """
1918 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001919 assert not cert.has_expired()
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001920
Rick Dean38a05c82009-07-18 01:41:30 -05001921 def test_digest(self):
1922 """
Alex Chanb00ede22017-01-30 07:24:40 +00001923 `X509.digest` returns a string giving ":"-separated hex-encoded
Alex Gaynor31287502015-09-05 16:11:27 -04001924 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001925 """
Paul Kehrera40898b2017-06-11 16:30:58 -10001926 cert = load_certificate(FILETYPE_PEM, old_root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00001927 assert (
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001928 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1929 # actually matters to the assertion (ie, another arbitrary, good
1930 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001931 # Digest verified with the command:
1932 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Alex Gaynor03737182020-07-23 20:40:46 -04001933 cert.digest("MD5")
1934 == b"19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"
1935 )
Rick Dean38a05c82009-07-18 01:41:30 -05001936
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001937 def _extcert(self, pkey, extensions):
1938 cert = X509()
David Benjamin6b799472020-06-24 17:14:16 -04001939 # Certificates with extensions must be X.509v3, which is encoded with a
1940 # version of two.
1941 cert.set_version(2)
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001942 cert.set_pubkey(pkey)
1943 cert.get_subject().commonName = "Unit Tests"
1944 cert.get_issuer().commonName = "Unit Tests"
Alex Gaynore7f51982016-09-11 11:48:14 -04001945 when = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001946 cert.set_notBefore(when)
1947 cert.set_notAfter(when)
1948
1949 cert.add_extensions(extensions)
Alex Gaynor03737182020-07-23 20:40:46 -04001950 cert.sign(pkey, "sha1")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001951 return load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04001952 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert)
1953 )
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001954
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001955 def test_extension_count(self):
1956 """
Alex Chanb00ede22017-01-30 07:24:40 +00001957 `X509.get_extension_count` returns the number of extensions
Alex Gaynor31287502015-09-05 16:11:27 -04001958 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001959 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001960 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04001961 ca = X509Extension(b"basicConstraints", True, b"CA:FALSE")
1962 key = X509Extension(b"keyUsage", True, b"digitalSignature")
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001963 subjectAltName = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -04001964 b"subjectAltName", True, b"DNS:example.com"
1965 )
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001966
1967 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001968 c = self._extcert(pkey, [])
Alex Chanb00ede22017-01-30 07:24:40 +00001969 assert c.get_extension_count() == 0
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001970
1971 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001972 c = self._extcert(pkey, [ca])
Alex Chanb00ede22017-01-30 07:24:40 +00001973 assert c.get_extension_count() == 1
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001974
1975 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001976 c = self._extcert(pkey, [ca, key, subjectAltName])
Alex Chanb00ede22017-01-30 07:24:40 +00001977 assert c.get_extension_count() == 3
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001978
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001979 def test_get_extension(self):
1980 """
Alex Chanb00ede22017-01-30 07:24:40 +00001981 `X509.get_extension` takes an integer and returns an
1982 `X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001983 """
1984 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04001985 ca = X509Extension(b"basicConstraints", True, b"CA:FALSE")
1986 key = X509Extension(b"keyUsage", True, b"digitalSignature")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001987 subjectAltName = X509Extension(
Alex Gaynor03737182020-07-23 20:40:46 -04001988 b"subjectAltName", False, b"DNS:example.com"
1989 )
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001990
1991 cert = self._extcert(pkey, [ca, key, subjectAltName])
1992
1993 ext = cert.get_extension(0)
Alex Chanb00ede22017-01-30 07:24:40 +00001994 assert isinstance(ext, X509Extension)
1995 assert ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04001996 assert ext.get_short_name() == b"basicConstraints"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001997
1998 ext = cert.get_extension(1)
Alex Chanb00ede22017-01-30 07:24:40 +00001999 assert isinstance(ext, X509Extension)
2000 assert ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04002001 assert ext.get_short_name() == b"keyUsage"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04002002
2003 ext = cert.get_extension(2)
Alex Chanb00ede22017-01-30 07:24:40 +00002004 assert isinstance(ext, X509Extension)
2005 assert not ext.get_critical()
Alex Gaynor03737182020-07-23 20:40:46 -04002006 assert ext.get_short_name() == b"subjectAltName"
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04002007
Alex Chanb00ede22017-01-30 07:24:40 +00002008 with pytest.raises(IndexError):
2009 cert.get_extension(-1)
2010 with pytest.raises(IndexError):
2011 cert.get_extension(4)
2012 with pytest.raises(TypeError):
2013 cert.get_extension("hello")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04002014
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002015 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04002016 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04002017 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002018 bytes and this value is reflected in the string representation of the
2019 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04002020 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002021 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04002022
2023 ext = cert.get_extension(3)
Alex Gaynor03737182020-07-23 20:40:46 -04002024 assert ext.get_short_name() == b"subjectAltName"
Alex Chanb00ede22017-01-30 07:24:40 +00002025 assert (
Alex Gaynore7f51982016-09-11 11:48:14 -04002026 b"DNS:altnull.python.org\x00example.com, "
2027 b"email:null@python.org\x00user@example.org, "
2028 b"URI:http://null.python.org\x00http://example.org, "
Alex Gaynor03737182020-07-23 20:40:46 -04002029 b"IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"
2030 == str(ext).encode("ascii")
2031 )
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04002032
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002033 def test_invalid_digest_algorithm(self):
2034 """
Alex Chanb00ede22017-01-30 07:24:40 +00002035 `X509.digest` raises `ValueError` if called with an unrecognized hash
2036 algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002037 """
2038 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002039 with pytest.raises(ValueError):
2040 cert.digest(BAD_DIGEST)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002041
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002042 def test_get_subject(self):
2043 """
Alex Chanb00ede22017-01-30 07:24:40 +00002044 `X509.get_subject` returns an `X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002045 """
2046 cert = load_certificate(FILETYPE_PEM, self.pemData)
2047 subj = cert.get_subject()
Alex Chanb00ede22017-01-30 07:24:40 +00002048 assert isinstance(subj, X509Name)
Alex Gaynor03737182020-07-23 20:40:46 -04002049 assert subj.get_components() == [
2050 (b"C", b"US"),
2051 (b"ST", b"IL"),
2052 (b"L", b"Chicago"),
2053 (b"O", b"Testing"),
2054 (b"CN", b"Testing Root CA"),
2055 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002056
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002057 def test_set_subject_wrong_args(self):
2058 """
Alex Chanb00ede22017-01-30 07:24:40 +00002059 `X509.set_subject` raises a `TypeError` if called with an argument not
2060 of type `X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002061 """
2062 cert = X509()
Alex Gaynor85b49702015-09-05 16:30:59 -04002063 with pytest.raises(TypeError):
Alex Chanb00ede22017-01-30 07:24:40 +00002064 cert.set_subject(None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002065
2066 def test_set_subject(self):
2067 """
Alex Chanb00ede22017-01-30 07:24:40 +00002068 `X509.set_subject` changes the subject of the certificate to the one
2069 passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002070 """
2071 cert = X509()
2072 name = cert.get_subject()
Alex Gaynor03737182020-07-23 20:40:46 -04002073 name.C = "AU"
2074 name.OU = "Unit Tests"
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002075 cert.set_subject(name)
Alex Gaynor03737182020-07-23 20:40:46 -04002076 assert cert.get_subject().get_components() == [
2077 (b"C", b"AU"),
2078 (b"OU", b"Unit Tests"),
2079 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002080
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002081 def test_get_issuer(self):
2082 """
Alex Chanb00ede22017-01-30 07:24:40 +00002083 `X509.get_issuer` returns an `X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002084 """
2085 cert = load_certificate(FILETYPE_PEM, self.pemData)
2086 subj = cert.get_issuer()
Alex Chanb00ede22017-01-30 07:24:40 +00002087 assert isinstance(subj, X509Name)
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04002088 comp = subj.get_components()
Alex Gaynor03737182020-07-23 20:40:46 -04002089 assert comp == [
2090 (b"C", b"US"),
2091 (b"ST", b"IL"),
2092 (b"L", b"Chicago"),
2093 (b"O", b"Testing"),
2094 (b"CN", b"Testing Root CA"),
2095 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002096
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002097 def test_set_issuer_wrong_args(self):
2098 """
Alex Chanb00ede22017-01-30 07:24:40 +00002099 `X509.set_issuer` raises a `TypeError` if called with an argument not
2100 of type `X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002101 """
2102 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002103 with pytest.raises(TypeError):
2104 cert.set_issuer(None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002105
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002106 def test_set_issuer(self):
2107 """
Alex Chanb00ede22017-01-30 07:24:40 +00002108 `X509.set_issuer` changes the issuer of the certificate to the
Alex Gaynor31287502015-09-05 16:11:27 -04002109 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002110 """
2111 cert = X509()
2112 name = cert.get_issuer()
Alex Gaynor03737182020-07-23 20:40:46 -04002113 name.C = "AU"
2114 name.OU = "Unit Tests"
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002115 cert.set_issuer(name)
Alex Gaynor03737182020-07-23 20:40:46 -04002116 assert cert.get_issuer().get_components() == [
2117 (b"C", b"AU"),
2118 (b"OU", b"Unit Tests"),
2119 ]
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002120
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002121 def test_get_pubkey_uninitialized(self):
2122 """
Alex Chanb00ede22017-01-30 07:24:40 +00002123 When called on a certificate with no public key, `X509.get_pubkey`
2124 raises `OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002125 """
2126 cert = X509()
Alex Chanb00ede22017-01-30 07:24:40 +00002127 with pytest.raises(Error):
2128 cert.get_pubkey()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04002129
Alex Gaynor7778e792016-07-03 23:38:48 -04002130 def test_set_pubkey_wrong_type(self):
2131 """
Alex Chanb00ede22017-01-30 07:24:40 +00002132 `X509.set_pubkey` raises `TypeError` when given an object of the
2133 wrong type.
Alex Gaynor7778e792016-07-03 23:38:48 -04002134 """
2135 cert = X509()
2136 with pytest.raises(TypeError):
2137 cert.set_pubkey(object())
2138
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002139 def test_subject_name_hash(self):
2140 """
Alex Chanb00ede22017-01-30 07:24:40 +00002141 `X509.subject_name_hash` returns the hash of the certificate's
Alex Gaynor31287502015-09-05 16:11:27 -04002142 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002143 """
2144 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor4cb05202019-02-02 11:06:41 -05002145 # SHA1
2146 assert cert.subject_name_hash() == 3278919224
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002147
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002148 def test_get_signature_algorithm(self):
2149 """
Alex Chanb00ede22017-01-30 07:24:40 +00002150 `X509.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002151 the algorithm used to sign the certificate.
2152 """
2153 cert = load_certificate(FILETYPE_PEM, self.pemData)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002154 assert b"sha256WithRSAEncryption" == cert.get_signature_algorithm()
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002155
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002156 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04002157 """
Alex Chanb00ede22017-01-30 07:24:40 +00002158 `X509.get_signature_algorithm` raises `ValueError` if the signature
2159 algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04002160 """
2161 # This certificate has been modified to indicate a bogus OID in the
2162 # signature algorithm field so that OpenSSL does not recognize it.
Alex Gaynore7f51982016-09-11 11:48:14 -04002163 certPEM = b"""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002164-----BEGIN CERTIFICATE-----
2165MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
2166EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
2167cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
2168MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
2169EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
2170CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
2171AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
2172+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
2173hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
2174BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
2175FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
2176dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
2177aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
2178MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
2179jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
2180PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
2181tgI5
2182-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -04002183"""
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002184 cert = load_certificate(FILETYPE_PEM, certPEM)
Alex Chanb00ede22017-01-30 07:24:40 +00002185 with pytest.raises(ValueError):
2186 cert.get_signature_algorithm()
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002187
Alex Gaynor37726112016-07-04 09:51:32 -04002188 def test_sign_bad_pubkey_type(self):
2189 """
Alex Chanb00ede22017-01-30 07:24:40 +00002190 `X509.sign` raises `TypeError` when called with the wrong type.
Alex Gaynor37726112016-07-04 09:51:32 -04002191 """
2192 cert = X509()
2193 with pytest.raises(TypeError):
2194 cert.sign(object(), b"sha256")
2195
Alex Gaynor9939ba12017-06-25 16:28:24 -04002196 def test_convert_from_cryptography(self):
2197 crypto_cert = x509.load_pem_x509_certificate(
2198 intermediate_cert_pem, backend
2199 )
2200 cert = X509.from_cryptography(crypto_cert)
2201
2202 assert isinstance(cert, X509)
2203 assert cert.get_version() == crypto_cert.version.value
2204
2205 def test_convert_from_cryptography_unsupported_type(self):
2206 with pytest.raises(TypeError):
2207 X509.from_cryptography(object())
2208
2209 def test_convert_to_cryptography_key(self):
2210 cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
2211 crypto_cert = cert.to_cryptography()
2212
2213 assert isinstance(crypto_cert, x509.Certificate)
2214 assert crypto_cert.version.value == cert.get_version()
2215
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002216
Alex Chan9e2a9932017-01-25 14:29:19 +00002217class TestX509Store(object):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002218 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002219 Test for `OpenSSL.crypto.X509Store`.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002220 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002221
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002222 def test_type(self):
2223 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002224 `X509Store` is a type object.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002225 """
Alex Gaynor03737182020-07-23 20:40:46 -04002226 assert is_consistent_type(X509Store, "X509Store")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002227
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002228 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002229 """
Alex Chan9e2a9932017-01-25 14:29:19 +00002230 `X509Store.add_cert` adds a `X509` instance to the certificate store.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002231 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002232 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002233 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002234 store.add_cert(cert)
2235
Alex Gaynor03737182020-07-23 20:40:46 -04002236 @pytest.mark.parametrize("cert", [None, 1.0, "cert", object()])
Alex Chanfb078d82017-04-20 11:16:15 +01002237 def test_add_cert_wrong_args(self, cert):
2238 """
2239 `X509Store.add_cert` raises `TypeError` if passed a non-X509 object
2240 as its first argument.
2241 """
2242 store = X509Store()
2243 with pytest.raises(TypeError):
2244 store.add_cert(cert)
2245
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002246 def test_add_cert_accepts_duplicate(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002247 """
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002248 `X509Store.add_cert` doesn't raise `OpenSSL.crypto.Error` if an attempt
2249 is made to add the same certificate to the store more than once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002250 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002251 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002252 store = X509Store()
2253 store.add_cert(cert)
Paul Kehrer0e6c5532018-08-23 10:52:15 -05002254 store.add_cert(cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002255
Sándor Oroszi43c97762020-09-11 17:17:31 +02002256 @pytest.mark.parametrize(
2257 "cafile, capath, call_cafile, call_capath",
2258 [
2259 (
2260 "/cafile" + NON_ASCII,
2261 None,
2262 b"/cafile" + NON_ASCII.encode(sys.getfilesystemencoding()),
2263 _ffi.NULL,
2264 ),
2265 (
2266 b"/cafile" + NON_ASCII.encode("utf-8"),
2267 None,
2268 b"/cafile" + NON_ASCII.encode("utf-8"),
2269 _ffi.NULL,
2270 ),
2271 (
2272 None,
2273 "/capath" + NON_ASCII,
2274 _ffi.NULL,
2275 b"/capath" + NON_ASCII.encode(sys.getfilesystemencoding()),
2276 ),
2277 (
2278 None,
2279 b"/capath" + NON_ASCII.encode("utf-8"),
2280 _ffi.NULL,
2281 b"/capath" + NON_ASCII.encode("utf-8"),
2282 ),
2283 ],
2284 )
2285 def test_load_locations_parameters(
2286 self, cafile, capath, call_cafile, call_capath, monkeypatch
2287 ):
2288 class LibMock(object):
2289 def load_locations(self, store, cafile, capath):
2290 self.cafile = cafile
2291 self.capath = capath
2292 return 1
2293
2294 lib_mock = LibMock()
2295 monkeypatch.setattr(
2296 _lib, "X509_STORE_load_locations", lib_mock.load_locations
2297 )
2298
2299 store = X509Store()
2300 store.load_locations(cafile=cafile, capath=capath)
2301
2302 assert call_cafile == lib_mock.cafile
2303 assert call_capath == lib_mock.capath
2304
2305 def test_load_locations_fails_when_all_args_are_none(self):
2306 store = X509Store()
2307 with pytest.raises(Error):
2308 store.load_locations(None, None)
2309
2310 def test_load_locations_raises_error_on_failure(self, tmpdir):
2311 invalid_ca_file = tmpdir.join("invalid.pem")
2312 invalid_ca_file.write("This is not a certificate")
2313
2314 store = X509Store()
2315 with pytest.raises(Error):
2316 store.load_locations(cafile=str(invalid_ca_file))
2317
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002318
Alex Chanb00ede22017-01-30 07:24:40 +00002319class TestPKCS12(object):
Rick Dean623ee362009-07-17 12:22:16 -05002320 """
Alex Chanb00ede22017-01-30 07:24:40 +00002321 Test for `OpenSSL.crypto.PKCS12` and `OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002322 """
Alex Gaynor03737182020-07-23 20:40:46 -04002323
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002324 def test_type(self):
2325 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05002326 `PKCS12` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002327 """
Alex Gaynor03737182020-07-23 20:40:46 -04002328 assert is_consistent_type(PKCS12, "PKCS12")
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002329
Rick Deanf94096c2009-07-18 14:23:06 -05002330 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002331 """
Alex Chanb00ede22017-01-30 07:24:40 +00002332 `PKCS12` returns a new instance of `PKCS12` with no certificate,
2333 private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05002334 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002335 p12 = PKCS12()
Alex Chanb00ede22017-01-30 07:24:40 +00002336 assert None is p12.get_certificate()
2337 assert None is p12.get_privatekey()
2338 assert None is p12.get_ca_certificates()
2339 assert None is p12.get_friendlyname()
Rick Dean623ee362009-07-17 12:22:16 -05002340
2341 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002342 """
Alex Chanb00ede22017-01-30 07:24:40 +00002343 The `PKCS12` setter functions (`set_certificate`, `set_privatekey`,
2344 `set_ca_certificates`, and `set_friendlyname`) raise `TypeError`
2345 when passed objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05002346 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002347 p12 = PKCS12()
Alex Chanb00ede22017-01-30 07:24:40 +00002348 for bad_arg in [3, PKey(), X509]:
2349 with pytest.raises(TypeError):
2350 p12.set_certificate(bad_arg)
Alex Gaynor03737182020-07-23 20:40:46 -04002351 for bad_arg in [3, "legbone", X509()]:
Alex Chanb00ede22017-01-30 07:24:40 +00002352 with pytest.raises(TypeError):
2353 p12.set_privatekey(bad_arg)
2354 for bad_arg in [3, X509(), (3, 4), (PKey(),)]:
2355 with pytest.raises(TypeError):
2356 p12.set_ca_certificates(bad_arg)
Alex Gaynor03737182020-07-23 20:40:46 -04002357 for bad_arg in [6, ("foo", "bar")]:
Alex Chanb00ede22017-01-30 07:24:40 +00002358 with pytest.raises(TypeError):
2359 p12.set_friendlyname(bad_arg)
Rick Dean623ee362009-07-17 12:22:16 -05002360
2361 def test_key_only(self):
2362 """
Alex Chanb00ede22017-01-30 07:24:40 +00002363 A `PKCS12` with only a private key can be exported using
2364 `PKCS12.export` and loaded again using `load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002365 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002366 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002367 p12 = PKCS12()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002368 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002369 p12.set_privatekey(pkey)
Alex Chanb00ede22017-01-30 07:24:40 +00002370 assert None is p12.get_certificate()
2371 assert pkey == p12.get_privatekey()
Rick Dean321a0512009-08-13 17:21:29 -05002372 try:
2373 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2374 except Error:
2375 # Some versions of OpenSSL will throw an exception
2376 # for this nearly useless PKCS12 we tried to generate:
2377 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2378 return
Rick Dean623ee362009-07-17 12:22:16 -05002379 p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002380 assert None is p12.get_ca_certificates()
2381 assert None is p12.get_certificate()
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002382
2383 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2384 # future this will be improved.
Alex Chanb00ede22017-01-30 07:24:40 +00002385 assert isinstance(p12.get_privatekey(), (PKey, type(None)))
Rick Dean623ee362009-07-17 12:22:16 -05002386
2387 def test_cert_only(self):
2388 """
Alex Chanb00ede22017-01-30 07:24:40 +00002389 A `PKCS12` with only a certificate can be exported using
2390 `PKCS12.export` and loaded again using `load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002391 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002392 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002393 p12 = PKCS12()
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002394 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002395 p12.set_certificate(cert)
Alex Chanb00ede22017-01-30 07:24:40 +00002396 assert cert == p12.get_certificate()
2397 assert None is p12.get_privatekey()
Rick Dean321a0512009-08-13 17:21:29 -05002398 try:
2399 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2400 except Error:
2401 # Some versions of OpenSSL will throw an exception
2402 # for this nearly useless PKCS12 we tried to generate:
2403 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2404 return
Rick Dean623ee362009-07-17 12:22:16 -05002405 p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002406 assert None is p12.get_privatekey()
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002407
2408 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
Alex Chanb00ede22017-01-30 07:24:40 +00002409 assert isinstance(p12.get_certificate(), (X509, type(None)))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002410
2411 # Oh ho. It puts the certificate into the ca certificates list, in
2412 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2413 # that to check to see if it reconstructed the certificate we expected
2414 # it to. At some point, hopefully this will change so that
2415 # p12.get_certificate() is actually what returns the loaded
2416 # certificate.
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002417 assert root_cert_pem == dump_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04002418 FILETYPE_PEM, p12.get_ca_certificates()[0]
2419 )
Rick Dean623ee362009-07-17 12:22:16 -05002420
Alex Gaynor03737182020-07-23 20:40:46 -04002421 def gen_pkcs12(
2422 self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None
2423 ):
Rick Dean623ee362009-07-17 12:22:16 -05002424 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002425 Generate a PKCS12 object with components from PEM. Verify that the set
2426 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002427 """
Rick Deanf94096c2009-07-18 14:23:06 -05002428 p12 = PKCS12()
2429 if cert_pem:
2430 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
Alex Chanb00ede22017-01-30 07:24:40 +00002431 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002432 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002433 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Alex Chanb00ede22017-01-30 07:24:40 +00002434 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002435 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002436 ret = p12.set_ca_certificates(
2437 (load_certificate(FILETYPE_PEM, ca_pem),)
2438 )
Alex Chanb00ede22017-01-30 07:24:40 +00002439 assert ret is None
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002440 if friendly_name:
2441 ret = p12.set_friendlyname(friendly_name)
Alex Chanb00ede22017-01-30 07:24:40 +00002442 assert ret is None
Rick Deanf94096c2009-07-18 14:23:06 -05002443 return p12
2444
Alex Gaynor03737182020-07-23 20:40:46 -04002445 def check_recovery(
2446 self, p12_str, key=None, cert=None, ca=None, passwd=b"", extra=()
2447 ):
Rick Deanf94096c2009-07-18 14:23:06 -05002448 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002449 Use openssl program to confirm three components are recoverable from a
2450 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002451 """
2452 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002453 recovered_key = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002454 p12_str,
2455 b"pkcs12",
2456 b"-nocerts",
2457 b"-nodes",
2458 b"-passin",
2459 b"pass:" + passwd,
2460 *extra
2461 )
2462 assert recovered_key[-len(key) :] == key
Rick Deanf94096c2009-07-18 14:23:06 -05002463 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002464 recovered_cert = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002465 p12_str,
2466 b"pkcs12",
2467 b"-clcerts",
2468 b"-nodes",
2469 b"-passin",
2470 b"pass:" + passwd,
2471 b"-nokeys",
2472 *extra
2473 )
2474 assert recovered_cert[-len(cert) :] == cert
Rick Deanf94096c2009-07-18 14:23:06 -05002475 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002476 recovered_cert = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002477 p12_str,
2478 b"pkcs12",
2479 b"-cacerts",
2480 b"-nodes",
2481 b"-passin",
2482 b"pass:" + passwd,
2483 b"-nokeys",
2484 *extra
2485 )
2486 assert recovered_cert[-len(ca) :] == ca
Rick Deanf94096c2009-07-18 14:23:06 -05002487
Stephen Holsapple38482622014-04-05 20:29:34 -07002488 def verify_pkcs12_container(self, p12):
2489 """
2490 Verify that the PKCS#12 container contains the correct client
2491 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002492
2493 :param p12: The PKCS12 instance to verify.
Alex Chanb00ede22017-01-30 07:24:40 +00002494 :type p12: `PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002495 """
2496 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2497 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Alex Gaynor03737182020-07-23 20:40:46 -04002498 assert (client_cert_pem, client_key_pem, None) == (
2499 cert_pem,
2500 key_pem,
2501 p12.get_ca_certificates(),
2502 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002503
Rick Deanf94096c2009-07-18 14:23:06 -05002504 def test_load_pkcs12(self):
2505 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002506 A PKCS12 string generated using the openssl command line can be loaded
Alex Chanb00ede22017-01-30 07:24:40 +00002507 with `load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002508 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002509 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002510 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002511 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002512 pem,
2513 b"pkcs12",
2514 b"-export",
2515 b"-clcerts",
2516 b"-passout",
Alex Gaynor03737182020-07-23 20:40:46 -04002517 b"pass:" + passwd,
Alex Gaynor85b49702015-09-05 16:30:59 -04002518 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002519 p12 = load_pkcs12(p12_str, passphrase=passwd)
2520 self.verify_pkcs12_container(p12)
2521
Abraham Martinc5484ba2015-03-25 15:33:05 +00002522 def test_load_pkcs12_text_passphrase(self):
2523 """
2524 A PKCS12 string generated using the openssl command line can be loaded
Alex Chanb00ede22017-01-30 07:24:40 +00002525 with `load_pkcs12` and its components extracted and examined.
Abraham Martinc5484ba2015-03-25 15:33:05 +00002526 Using text as passphrase instead of bytes. DeprecationWarning expected.
2527 """
2528 pem = client_key_pem + client_cert_pem
2529 passwd = b"whatever"
Alex Gaynor03737182020-07-23 20:40:46 -04002530 p12_str = _runopenssl(
2531 pem,
2532 b"pkcs12",
2533 b"-export",
2534 b"-clcerts",
2535 b"-passout",
2536 b"pass:" + passwd,
2537 )
Alex Chanb00ede22017-01-30 07:24:40 +00002538 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00002539 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002540 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Alex Gaynor03737182020-07-23 20:40:46 -04002541 msg = "{0} for passphrase is no longer accepted, use bytes".format(
2542 WARNING_TYPE_EXPECTED
2543 )
2544 assert msg == str(w[-1].message)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002545
Abraham Martinc5484ba2015-03-25 15:33:05 +00002546 self.verify_pkcs12_container(p12)
2547
Stephen Holsapple38482622014-04-05 20:29:34 -07002548 def test_load_pkcs12_no_passphrase(self):
2549 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002550 A PKCS12 string generated using openssl command line can be loaded with
Alex Chanb00ede22017-01-30 07:24:40 +00002551 `load_pkcs12` without a passphrase and its components extracted
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002552 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002553 """
2554 pem = client_key_pem + client_cert_pem
2555 p12_str = _runopenssl(
Alex Gaynor03737182020-07-23 20:40:46 -04002556 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:"
2557 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002558 p12 = load_pkcs12(p12_str)
2559 self.verify_pkcs12_container(p12)
2560
Stephen Holsapple38482622014-04-05 20:29:34 -07002561 def _dump_and_load(self, dump_passphrase, load_passphrase):
2562 """
2563 A helper method to dump and load a PKCS12 object.
2564 """
2565 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2566 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2567 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2568
Stephen Holsapple38482622014-04-05 20:29:34 -07002569 def test_load_pkcs12_null_passphrase_load_empty(self):
2570 """
2571 A PKCS12 string can be dumped with a null passphrase, loaded with an
Alex Chanb00ede22017-01-30 07:24:40 +00002572 empty passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002573 extracted and examined.
2574 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002575 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002576 self._dump_and_load(dump_passphrase=None, load_passphrase=b"")
2577 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002578
Stephen Holsapple38482622014-04-05 20:29:34 -07002579 def test_load_pkcs12_null_passphrase_load_null(self):
2580 """
2581 A PKCS12 string can be dumped with a null passphrase, loaded with a
Alex Chanb00ede22017-01-30 07:24:40 +00002582 null passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002583 extracted and examined.
2584 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002585 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002586 self._dump_and_load(dump_passphrase=None, load_passphrase=None)
2587 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002588
Stephen Holsapple38482622014-04-05 20:29:34 -07002589 def test_load_pkcs12_empty_passphrase_load_empty(self):
2590 """
2591 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Alex Chanb00ede22017-01-30 07:24:40 +00002592 empty passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002593 extracted and examined.
2594 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002595 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002596 self._dump_and_load(dump_passphrase=b"", load_passphrase=b"")
2597 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002598
Stephen Holsapple38482622014-04-05 20:29:34 -07002599 def test_load_pkcs12_empty_passphrase_load_null(self):
2600 """
2601 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Alex Chanb00ede22017-01-30 07:24:40 +00002602 null passphrase with `load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002603 extracted and examined.
2604 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002605 self.verify_pkcs12_container(
Alex Gaynor03737182020-07-23 20:40:46 -04002606 self._dump_and_load(dump_passphrase=b"", load_passphrase=None)
2607 )
Rick Deanf94096c2009-07-18 14:23:06 -05002608
Rick Deanee568302009-07-24 09:56:29 -05002609 def test_load_pkcs12_garbage(self):
2610 """
Alex Chanb00ede22017-01-30 07:24:40 +00002611 `load_pkcs12` raises `OpenSSL.crypto.Error` when passed
Alex Gaynor85b49702015-09-05 16:30:59 -04002612 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002613 """
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05002614 passwd = b"whatever"
Alex Chanb00ede22017-01-30 07:24:40 +00002615 with pytest.raises(Error) as err:
Alex Gaynor03737182020-07-23 20:40:46 -04002616 load_pkcs12(b"fruit loops", passwd)
2617 assert err.value.args[0][0][0] == "asn1 encoding routines"
Alex Chanb00ede22017-01-30 07:24:40 +00002618 assert len(err.value.args[0][0]) == 3
Rick Deanee568302009-07-24 09:56:29 -05002619
Rick Deanf94096c2009-07-18 14:23:06 -05002620 def test_replace(self):
2621 """
Alex Chanb00ede22017-01-30 07:24:40 +00002622 `PKCS12.set_certificate` replaces the certificate in a PKCS12
2623 cluster. `PKCS12.set_privatekey` replaces the private key.
2624 `PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002625 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002626 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2627 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2628 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002629 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002630 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002631 p12.set_ca_certificates([root_cert]) # not a tuple
Alex Chanb00ede22017-01-30 07:24:40 +00002632 assert 1 == len(p12.get_ca_certificates())
2633 assert root_cert == p12.get_ca_certificates()[0]
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002634 p12.set_ca_certificates([client_cert, root_cert])
Alex Chanb00ede22017-01-30 07:24:40 +00002635 assert 2 == len(p12.get_ca_certificates())
2636 assert client_cert == p12.get_ca_certificates()[0]
2637 assert root_cert == p12.get_ca_certificates()[1]
Rick Deanf94096c2009-07-18 14:23:06 -05002638
Rick Deanf94096c2009-07-18 14:23:06 -05002639 def test_friendly_name(self):
2640 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002641 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Chanb00ede22017-01-30 07:24:40 +00002642 `PKCS12.get_friendlyname` and `PKCS12_set_friendlyname`, and a
2643 `PKCS12` with a friendly name set can be dumped with `PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002644 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002645 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002646 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04002647 for friendly_name in [b"Serverlicious", None, b"###"]:
Rick Dean42d69e12009-07-20 11:36:08 -05002648 p12.set_friendlyname(friendly_name)
Alex Chanb00ede22017-01-30 07:24:40 +00002649 assert p12.get_friendlyname() == friendly_name
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002650 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002651 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Alex Chanb00ede22017-01-30 07:24:40 +00002652 assert p12.get_friendlyname() == reloaded_p12.get_friendlyname()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002653 # We would use the openssl program to confirm the friendly
2654 # name, but it is not possible. The pkcs12 command
2655 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002656 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002657 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002658 dumped_p12,
2659 key=server_key_pem,
2660 cert=server_cert_pem,
2661 ca=root_cert_pem,
2662 passwd=passwd,
2663 )
Rick Deanf94096c2009-07-18 14:23:06 -05002664
Rick Deanf94096c2009-07-18 14:23:06 -05002665 def test_various_empty_passphrases(self):
2666 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002667 Test that missing, None, and '' passphrases are identical for PKCS12
2668 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002669 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002670 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002671 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002672 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2673 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2674 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2675 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2676 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002677 dumped_p12,
2678 key=client_key_pem,
2679 cert=client_cert_pem,
2680 ca=root_cert_pem,
2681 passwd=passwd,
2682 )
Rick Deanf94096c2009-07-18 14:23:06 -05002683
Rick Deanf94096c2009-07-18 14:23:06 -05002684 def test_removing_ca_cert(self):
2685 """
Alex Chanb00ede22017-01-30 07:24:40 +00002686 Passing `None` to `PKCS12.set_ca_certificates` removes all CA
2687 certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002688 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002689 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2690 p12.set_ca_certificates(None)
Alex Chanb00ede22017-01-30 07:24:40 +00002691 assert None is p12.get_ca_certificates()
Rick Deanf94096c2009-07-18 14:23:06 -05002692
Rick Deanf94096c2009-07-18 14:23:06 -05002693 def test_export_without_mac(self):
2694 """
Alex Chanb00ede22017-01-30 07:24:40 +00002695 Exporting a PKCS12 with a `maciter` of `-1` excludes the MAC entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002696 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002697 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002698 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002699 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002700 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002701 dumped_p12,
2702 key=server_key_pem,
2703 cert=server_cert_pem,
2704 passwd=passwd,
2705 extra=(b"-nomacver",),
2706 )
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002707
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002708 def test_load_without_mac(self):
2709 """
2710 Loading a PKCS12 without a MAC does something other than crash.
2711 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002712 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002713 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2714 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002715 try:
2716 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2717 # The person who generated this PCKS12 should be flogged,
2718 # or better yet we should have a means to determine
2719 # whether a PCKS12 had a MAC that was verified.
2720 # Anyway, libopenssl chooses to allow it, so the
2721 # pyopenssl binding does as well.
Alex Chanb00ede22017-01-30 07:24:40 +00002722 assert isinstance(recovered_p12, PKCS12)
Rick Dean321a0512009-08-13 17:21:29 -05002723 except Error:
2724 # Failing here with an exception is preferred as some openssl
2725 # versions do.
2726 pass
Rick Dean623ee362009-07-17 12:22:16 -05002727
Rick Dean25bcc1f2009-07-20 11:53:13 -05002728 def test_zero_len_list_for_ca(self):
2729 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002730 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002731 """
Alex Gaynor03737182020-07-23 20:40:46 -04002732 passwd = b"Hobie 18"
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002733 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002734 p12.set_ca_certificates([])
Alex Chanb00ede22017-01-30 07:24:40 +00002735 assert () == p12.get_ca_certificates()
Alex Gaynor85b49702015-09-05 16:30:59 -04002736 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2737 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002738 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=passwd
2739 )
Rick Dean25bcc1f2009-07-20 11:53:13 -05002740
Rick Deanf94096c2009-07-18 14:23:06 -05002741 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002742 """
Alex Chanb00ede22017-01-30 07:24:40 +00002743 All the arguments to `PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002744 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002745 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002746 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002747 self.check_recovery(
Alex Gaynor03737182020-07-23 20:40:46 -04002748 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b""
2749 )
Rick Deanf94096c2009-07-18 14:23:06 -05002750
Abraham Martinc5484ba2015-03-25 15:33:05 +00002751 def test_export_without_bytes(self):
2752 """
Alex Chanb00ede22017-01-30 07:24:40 +00002753 Test `PKCS12.export` with text not bytes as passphrase
Abraham Martinc5484ba2015-03-25 15:33:05 +00002754 """
2755 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2756
Alex Chanb00ede22017-01-30 07:24:40 +00002757 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00002758 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002759 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Alex Gaynor03737182020-07-23 20:40:46 -04002760 msg = "{0} for passphrase is no longer accepted, use bytes".format(
2761 WARNING_TYPE_EXPECTED
2762 )
2763 assert msg == str(w[-1].message)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002764 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002765 dumped_p12,
2766 key=server_key_pem,
2767 cert=server_cert_pem,
Alex Gaynor03737182020-07-23 20:40:46 -04002768 passwd=b"randomtext",
Alex Gaynor791212d2015-09-05 15:46:08 -04002769 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002770
Rick Deanf94096c2009-07-18 14:23:06 -05002771 def test_key_cert_mismatch(self):
2772 """
Alex Chanb00ede22017-01-30 07:24:40 +00002773 `PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002774 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002775 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002776 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00002777 with pytest.raises(Error):
2778 p12.export()
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002779
2780
Rick Dean4c9ad612009-07-17 15:05:22 -05002781def _runopenssl(pem, *args):
2782 """
2783 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002784 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002785 """
Alex Gaynor6cbc69a2017-07-25 09:07:04 -04002786 proc = Popen([b"openssl"] + list(args), stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002787 proc.stdin.write(pem)
2788 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002789 output = proc.stdout.read()
2790 proc.stdout.close()
2791 proc.wait()
2792 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002793
2794
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002795class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002796 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002797 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002798 """
Alex Gaynor03737182020-07-23 20:40:46 -04002799
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002800 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002801 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002802 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002803 """
2804 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002805
2806 assert True is key._only_public
2807 assert 2048 == key.bits()
2808 assert TYPE_RSA == key.type()
2809
2810 def test_invalid_type(self):
2811 """
2812 load_publickey doesn't support FILETYPE_TEXT.
2813 """
2814 with pytest.raises(ValueError):
2815 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2816
2817 def test_invalid_key_format(self):
2818 """
2819 load_publickey explodes on incorrect keys.
2820 """
2821 with pytest.raises(Error):
2822 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2823
2824 def test_tolerates_unicode_strings(self):
2825 """
2826 load_publickey works with text strings, not just bytes.
2827 """
Alex Gaynor03737182020-07-23 20:40:46 -04002828 serialized = cleartextPublicKeyPEM.decode("ascii")
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002829 key = load_publickey(FILETYPE_PEM, serialized)
2830 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2831
2832 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002833
2834
Alex Chanb00ede22017-01-30 07:24:40 +00002835class TestFunction(object):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002836 """
Alex Chanb00ede22017-01-30 07:24:40 +00002837 Tests for free-functions in the `OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002838 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002839
2840 def test_load_privatekey_invalid_format(self):
2841 """
Alex Chanb00ede22017-01-30 07:24:40 +00002842 `load_privatekey` raises `ValueError` if passed an unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002843 """
Alex Chanb00ede22017-01-30 07:24:40 +00002844 with pytest.raises(ValueError):
2845 load_privatekey(100, root_key_pem)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002846
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002847 def test_load_privatekey_invalid_passphrase_type(self):
2848 """
Alex Chanb00ede22017-01-30 07:24:40 +00002849 `load_privatekey` raises `TypeError` if passed a passphrase that is
2850 neither a `str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002851 """
Alex Chanb00ede22017-01-30 07:24:40 +00002852 with pytest.raises(TypeError):
2853 load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002854 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object()
2855 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002856
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002857 def test_load_privatekey_wrongPassphrase(self):
2858 """
Alex Chanb00ede22017-01-30 07:24:40 +00002859 `load_privatekey` raises `OpenSSL.crypto.Error` when it is passed an
2860 encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002861 """
Alex Chanb00ede22017-01-30 07:24:40 +00002862 with pytest.raises(Error) as err:
2863 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, b"quack")
2864 assert err.value.args[0] != []
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002865
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002866 def test_load_privatekey_passphraseWrongType(self):
2867 """
Alex Chanb00ede22017-01-30 07:24:40 +00002868 `load_privatekey` raises `ValueError` when it is passeda passphrase
2869 with a private key encoded in a format, that doesn't support
2870 encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002871 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05002872 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002873 blob = dump_privatekey(FILETYPE_ASN1, key)
Alex Chanb00ede22017-01-30 07:24:40 +00002874 with pytest.raises(ValueError):
2875 load_privatekey(FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002876
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002877 def test_load_privatekey_passphrase(self):
2878 """
Alex Chanb00ede22017-01-30 07:24:40 +00002879 `load_privatekey` can create a `PKey` object from an encrypted PEM
2880 string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002881 """
2882 key = load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002883 FILETYPE_PEM,
2884 encryptedPrivateKeyPEM,
2885 encryptedPrivateKeyPEMPassphrase,
2886 )
Alex Gaynor01f90a12019-02-07 09:14:48 -05002887 assert isinstance(key, PKey)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002888
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002889 def test_load_privatekey_passphrase_exception(self):
2890 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002891 If the passphrase callback raises an exception, that exception is
Alex Chanb00ede22017-01-30 07:24:40 +00002892 raised by `load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002893 """
Alex Gaynor03737182020-07-23 20:40:46 -04002894
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002895 def cb(ignored):
2896 raise ArithmeticError
2897
Alex Gaynor791212d2015-09-05 15:46:08 -04002898 with pytest.raises(ArithmeticError):
2899 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002900
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002901 def test_load_privatekey_wrongPassphraseCallback(self):
2902 """
Alex Chanb00ede22017-01-30 07:24:40 +00002903 `load_privatekey` raises `OpenSSL.crypto.Error` when it
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002904 is passed an encrypted PEM and a passphrase callback which returns an
2905 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002906 """
2907 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002908
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002909 def cb(*a):
2910 called.append(None)
Alex Gaynore7f51982016-09-11 11:48:14 -04002911 return b"quack"
Alex Gaynor03737182020-07-23 20:40:46 -04002912
Alex Chanb00ede22017-01-30 07:24:40 +00002913 with pytest.raises(Error) as err:
2914 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2915 assert called
2916 assert err.value.args[0] != []
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002917
2918 def test_load_privatekey_passphraseCallback(self):
2919 """
Alex Chanb00ede22017-01-30 07:24:40 +00002920 `load_privatekey` can create a `PKey` object from an encrypted PEM
2921 string if given a passphrase callback which returns the correct
2922 password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002923 """
2924 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002925
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002926 def cb(writing):
2927 called.append(writing)
2928 return encryptedPrivateKeyPEMPassphrase
Alex Gaynor03737182020-07-23 20:40:46 -04002929
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002930 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Alex Gaynor01f90a12019-02-07 09:14:48 -05002931 assert isinstance(key, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00002932 assert called == [False]
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002933
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002934 def test_load_privatekey_passphrase_wrong_return_type(self):
2935 """
Alex Chanb00ede22017-01-30 07:24:40 +00002936 `load_privatekey` raises `ValueError` if the passphrase callback
2937 returns something other than a byte string.
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002938 """
Alex Chanb00ede22017-01-30 07:24:40 +00002939 with pytest.raises(ValueError):
2940 load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04002941 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3
2942 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002943
Alex Chanfb078d82017-04-20 11:16:15 +01002944 def test_dump_privatekey_wrong_args(self):
2945 """
2946 `dump_privatekey` raises `TypeError` if called with a `cipher`
2947 argument but no `passphrase` argument.
2948 """
2949 key = PKey()
2950 key.generate_key(TYPE_RSA, 512)
2951 with pytest.raises(TypeError):
2952 dump_privatekey(FILETYPE_PEM, key, cipher=GOOD_CIPHER)
2953
Paul Kehrercded9932017-06-29 18:43:42 -05002954 def test_dump_privatekey_not_rsa_key(self):
2955 """
2956 `dump_privatekey` raises `TypeError` if called with a key that is
2957 not RSA.
2958 """
2959 key = PKey()
2960 key.generate_key(TYPE_DSA, 512)
2961 with pytest.raises(TypeError):
2962 dump_privatekey(FILETYPE_TEXT, key)
2963
2964 def test_dump_privatekey_invalid_pkey(self):
2965 with pytest.raises(TypeError):
2966 dump_privatekey(FILETYPE_TEXT, object())
2967
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002968 def test_dump_privatekey_unknown_cipher(self):
2969 """
Alex Chanb00ede22017-01-30 07:24:40 +00002970 `dump_privatekey` raises `ValueError` if called with an unrecognized
2971 cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002972 """
2973 key = PKey()
2974 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00002975 with pytest.raises(ValueError):
2976 dump_privatekey(FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002977
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002978 def test_dump_privatekey_invalid_passphrase_type(self):
2979 """
Alex Chanb00ede22017-01-30 07:24:40 +00002980 `dump_privatekey` raises `TypeError` if called with a passphrase which
2981 is neither a `str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002982 """
2983 key = PKey()
2984 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00002985 with pytest.raises(TypeError):
2986 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002987
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002988 def test_dump_privatekey_invalid_filetype(self):
2989 """
Alex Chanb00ede22017-01-30 07:24:40 +00002990 `dump_privatekey` raises `ValueError` if called with an unrecognized
2991 filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002992 """
2993 key = PKey()
2994 key.generate_key(TYPE_RSA, 512)
Alex Chanb00ede22017-01-30 07:24:40 +00002995 with pytest.raises(ValueError):
2996 dump_privatekey(100, key)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002997
Alex Chanb00ede22017-01-30 07:24:40 +00002998 def test_load_privatekey_passphrase_callback_length(self):
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002999 """
Alex Chanb00ede22017-01-30 07:24:40 +00003000 `crypto.load_privatekey` should raise an error when the passphrase
3001 provided by the callback is too long, not silently truncate it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003002 """
Alex Gaynor03737182020-07-23 20:40:46 -04003003
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003004 def cb(ignored):
3005 return "a" * 1025
3006
Alex Gaynor791212d2015-09-05 15:46:08 -04003007 with pytest.raises(ValueError):
3008 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003009
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003010 def test_dump_privatekey_passphrase(self):
3011 """
Alex Chanb00ede22017-01-30 07:24:40 +00003012 `dump_privatekey` writes an encrypted PEM when given a passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003013 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003014 passphrase = b"foo"
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003015 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003016 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
Alex Gaynor12576002019-11-18 00:18:50 -05003017 assert isinstance(pem, bytes)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003018 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
Alex Gaynor01f90a12019-02-07 09:14:48 -05003019 assert isinstance(loadedKey, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00003020 assert loadedKey.type() == key.type()
3021 assert loadedKey.bits() == key.bits()
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003022
Alex Chanb00ede22017-01-30 07:24:40 +00003023 def test_dump_privatekey_passphrase_wrong_type(self):
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003024 """
Alex Chanb00ede22017-01-30 07:24:40 +00003025 `dump_privatekey` raises `ValueError` when it is passed a passphrase
3026 with a private key encoded in a format, that doesn't support
3027 encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003028 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003029 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor791212d2015-09-05 15:46:08 -04003030 with pytest.raises(ValueError):
3031 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01003032
Rick Dean5b7b6372009-04-01 11:34:06 -05003033 def test_dump_certificate(self):
3034 """
Alex Chanb00ede22017-01-30 07:24:40 +00003035 `dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05003036 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003037 pemData = root_cert_pem + root_key_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003038 cert = load_certificate(FILETYPE_PEM, pemData)
3039 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003040 assert dumped_pem == root_cert_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003041 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003042 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Alex Chanb00ede22017-01-30 07:24:40 +00003043 assert dumped_der == good_der
Rick Dean5b7b6372009-04-01 11:34:06 -05003044 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
3045 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003046 assert dumped_pem2 == root_cert_pem
Rick Dean5b7b6372009-04-01 11:34:06 -05003047 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003048 assert len(dumped_text) > 500
Rick Dean5b7b6372009-04-01 11:34:06 -05003049
Alex Gaynor37726112016-07-04 09:51:32 -04003050 def test_dump_certificate_bad_type(self):
3051 """
Alex Chanb00ede22017-01-30 07:24:40 +00003052 `dump_certificate` raises a `ValueError` if it's called with
Alex Gaynor37726112016-07-04 09:51:32 -04003053 a bad type.
3054 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003055 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Gaynor37726112016-07-04 09:51:32 -04003056 with pytest.raises(ValueError):
3057 dump_certificate(object(), cert)
3058
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003059 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05003060 """
Alex Chanb00ede22017-01-30 07:24:40 +00003061 `dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003062 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003063 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Chanb00ede22017-01-30 07:24:40 +00003064 assert key.check()
Rick Dean5b7b6372009-04-01 11:34:06 -05003065 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003066 assert dumped_pem == normalized_root_key_pem
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003067
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003068 def test_dump_privatekey_asn1(self):
3069 """
Alex Chanb00ede22017-01-30 07:24:40 +00003070 `dump_privatekey` writes a DER
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003071 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003072 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003073
Rick Dean5b7b6372009-04-01 11:34:06 -05003074 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003075 assert dumped_der == root_key_der
3076
3077 def test_load_privatekey_asn1(self):
3078 """
3079 `dump_privatekey` writes a DER
3080 """
3081 key = load_privatekey(FILETYPE_ASN1, root_key_der)
3082 assert key.bits() == 3072
3083 assert key.type() == TYPE_RSA
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003084
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003085 def test_dump_privatekey_text(self):
3086 """
Alex Chanb00ede22017-01-30 07:24:40 +00003087 `dump_privatekey` writes a text
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003088 """
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003089 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Rick Dean5b7b6372009-04-01 11:34:06 -05003090 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003091 assert len(dumped_text) > 500
Rick Dean5b7b6372009-04-01 11:34:06 -05003092
Cory Benfield6492f7c2015-10-27 16:57:58 +09003093 def test_dump_publickey_pem(self):
3094 """
Cory Benfield11c10192015-10-27 17:23:03 +09003095 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09003096 """
3097 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3098 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09003099 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09003100
3101 def test_dump_publickey_asn1(self):
3102 """
Cory Benfield11c10192015-10-27 17:23:03 +09003103 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09003104 """
3105 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3106 dumped_der = dump_publickey(FILETYPE_ASN1, key)
3107 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
3108 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09003109 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09003110
Cory Benfielde02c7d82015-10-27 17:34:49 +09003111 def test_dump_publickey_invalid_type(self):
3112 """
3113 dump_publickey doesn't support FILETYPE_TEXT.
3114 """
3115 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
3116
3117 with pytest.raises(ValueError):
3118 dump_publickey(FILETYPE_TEXT, key)
3119
Rick Dean5b7b6372009-04-01 11:34:06 -05003120 def test_dump_certificate_request(self):
3121 """
Alex Chanb00ede22017-01-30 07:24:40 +00003122 `dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05003123 """
Alex Gaynor31287502015-09-05 16:11:27 -04003124 req = load_certificate_request(
Alex Gaynor03737182020-07-23 20:40:46 -04003125 FILETYPE_PEM, cleartextCertificateRequestPEM
3126 )
Rick Dean5b7b6372009-04-01 11:34:06 -05003127 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
Alex Chanb00ede22017-01-30 07:24:40 +00003128 assert dumped_pem == cleartextCertificateRequestPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003129 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003130 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Alex Chanb00ede22017-01-30 07:24:40 +00003131 assert dumped_der == good_der
Rick Dean5b7b6372009-04-01 11:34:06 -05003132 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
3133 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
Alex Chanb00ede22017-01-30 07:24:40 +00003134 assert dumped_pem2 == cleartextCertificateRequestPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05003135 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003136 assert len(dumped_text) > 500
Alex Chanb00ede22017-01-30 07:24:40 +00003137 with pytest.raises(ValueError):
3138 dump_certificate_request(100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05003139
Alex Chanb00ede22017-01-30 07:24:40 +00003140 def test_dump_privatekey_passphrase_callback(self):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003141 """
Alex Chanb00ede22017-01-30 07:24:40 +00003142 `dump_privatekey` writes an encrypted PEM when given a callback
Alex Gaynor791212d2015-09-05 15:46:08 -04003143 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003144 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003145 passphrase = b"foo"
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003146 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003147
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003148 def cb(writing):
3149 called.append(writing)
3150 return passphrase
Alex Gaynor03737182020-07-23 20:40:46 -04003151
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003152 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003153 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Alex Gaynor12576002019-11-18 00:18:50 -05003154 assert isinstance(pem, bytes)
Alex Chanb00ede22017-01-30 07:24:40 +00003155 assert called == [True]
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04003156 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
Alex Gaynor01f90a12019-02-07 09:14:48 -05003157 assert isinstance(loadedKey, PKey)
Alex Chanb00ede22017-01-30 07:24:40 +00003158 assert loadedKey.type() == key.type()
3159 assert loadedKey.bits() == key.bits()
Rick Dean5b7b6372009-04-01 11:34:06 -05003160
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003161 def test_dump_privatekey_passphrase_exception(self):
3162 """
Alex Chanb00ede22017-01-30 07:24:40 +00003163 `dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003164 by the passphrase callback.
3165 """
Alex Gaynor03737182020-07-23 20:40:46 -04003166
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003167 def cb(ignored):
3168 raise ArithmeticError
3169
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003170 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04003171 with pytest.raises(ArithmeticError):
3172 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01003173
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003174 def test_dump_privatekey_passphraseCallbackLength(self):
3175 """
Alex Chanb00ede22017-01-30 07:24:40 +00003176 `crypto.dump_privatekey` should raise an error when the passphrase
3177 provided by the callback is too long, not silently truncate it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003178 """
Alex Gaynor03737182020-07-23 20:40:46 -04003179
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003180 def cb(ignored):
3181 return "a" * 1025
3182
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003183 key = load_privatekey(FILETYPE_PEM, root_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04003184 with pytest.raises(ValueError):
3185 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01003186
Huw Jonescdd66962020-10-13 05:14:19 +01003187 def test_dump_privatekey_truncated(self):
3188 """
3189 `crypto.dump_privatekey` should not truncate a passphrase that contains
3190 a null byte.
3191 """
3192 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3193 passphrase = b"foo\x00bar"
3194 truncated_passphrase = passphrase.split(b"\x00", 1)[0]
3195
3196 # By dumping with the full passphrase load should raise an error if we
3197 # try to load using the truncated passphrase. If dump truncated the
3198 # passphrase, then we WILL load the privatekey and the test fails
3199 encrypted_key_pem = dump_privatekey(
3200 FILETYPE_PEM, key, "AES-256-CBC", passphrase
3201 )
3202 with pytest.raises(Error):
3203 load_privatekey(
3204 FILETYPE_PEM, encrypted_key_pem, truncated_passphrase
3205 )
3206
3207 def test_load_privatekey_truncated(self):
3208 """
3209 `crypto.load_privatekey` should not truncate a passphrase that contains
3210 a null byte.
3211 """
3212 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3213 passphrase = b"foo\x00bar"
3214 truncated_passphrase = passphrase.split(b"\x00", 1)[0]
3215
3216 # By dumping using the truncated passphrase load should raise an error
3217 # if we try to load using the full passphrase. If load truncated the
3218 # passphrase, then we WILL load the privatekey and the test fails
3219 encrypted_key_pem = dump_privatekey(
3220 FILETYPE_PEM, key, "AES-256-CBC", truncated_passphrase
3221 )
3222 with pytest.raises(Error):
3223 load_privatekey(FILETYPE_PEM, encrypted_key_pem, passphrase)
3224
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003225 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003226 """
Alex Chanb00ede22017-01-30 07:24:40 +00003227 `load_pkcs7_data` accepts a PKCS#7 string and returns an instance of
3228 `PKCS`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003229 """
3230 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003231 assert isinstance(pkcs7, PKCS7)
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003232
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003233 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07003234 """
Alex Chanb00ede22017-01-30 07:24:40 +00003235 `load_pkcs7_data` accepts a bytes containing ASN1 data representing
3236 PKCS#7 and returns an instance of `PKCS7`.
Alex Gaynor9875a912014-08-14 13:35:05 -07003237 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003238 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
Alex Chanb00ede22017-01-30 07:24:40 +00003239 assert isinstance(pkcs7, PKCS7)
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07003240
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003241 def test_load_pkcs7_data_invalid(self):
3242 """
Alex Chanb00ede22017-01-30 07:24:40 +00003243 If the data passed to `load_pkcs7_data` is invalid, `Error` is raised.
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003244 """
Alex Chanb00ede22017-01-30 07:24:40 +00003245 with pytest.raises(Error):
3246 load_pkcs7_data(FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003247
Alex Gaynor09a386e2016-07-03 09:32:44 -04003248 def test_load_pkcs7_type_invalid(self):
3249 """
Alex Chanb00ede22017-01-30 07:24:40 +00003250 If the type passed to `load_pkcs7_data`, `ValueError` is raised.
Alex Gaynor09a386e2016-07-03 09:32:44 -04003251 """
3252 with pytest.raises(ValueError):
3253 load_pkcs7_data(object(), b"foo")
3254
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08003255
Alex Chan9e2a9932017-01-25 14:29:19 +00003256class TestLoadCertificate(object):
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003257 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003258 Tests for `load_certificate_request`.
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003259 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003260
Alex Chan9e2a9932017-01-25 14:29:19 +00003261 def test_bad_file_type(self):
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003262 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003263 If the file type passed to `load_certificate_request` is neither
3264 `FILETYPE_PEM` nor `FILETYPE_ASN1` then `ValueError` is raised.
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003265 """
Alex Gaynor7778e792016-07-03 23:38:48 -04003266 with pytest.raises(ValueError):
3267 load_certificate_request(object(), b"")
3268 with pytest.raises(ValueError):
3269 load_certificate(object(), b"")
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003270
Alex Gaynor37726112016-07-04 09:51:32 -04003271 def test_bad_certificate(self):
3272 """
Alex Chan9e2a9932017-01-25 14:29:19 +00003273 If the bytes passed to `load_certificate` are not a valid certificate,
3274 an exception is raised.
Alex Gaynor37726112016-07-04 09:51:32 -04003275 """
3276 with pytest.raises(Error):
3277 load_certificate(FILETYPE_ASN1, b"lol")
3278
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05003279
Alex Chanb00ede22017-01-30 07:24:40 +00003280class TestPKCS7(object):
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003281 """
Alex Chanb00ede22017-01-30 07:24:40 +00003282 Tests for `PKCS7`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003283 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003284
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003285 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003286 """
Alex Chanb00ede22017-01-30 07:24:40 +00003287 `PKCS7.type_is_signed` returns `True` if the PKCS7 object is of
3288 the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003289 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003290 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003291 assert pkcs7.type_is_signed()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003292
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003293 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003294 """
Alex Chanb00ede22017-01-30 07:24:40 +00003295 `PKCS7.type_is_enveloped` returns `False` if the PKCS7 object is not
3296 of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003297 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003298 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003299 assert not pkcs7.type_is_enveloped()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003300
Alex Chanb00ede22017-01-30 07:24:40 +00003301 def test_type_is_signed_and_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003302 """
Alex Chanb00ede22017-01-30 07:24:40 +00003303 `PKCS7.type_is_signedAndEnveloped` returns `False`
Alex Gaynor791212d2015-09-05 15:46:08 -04003304 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003305 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003306 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003307 assert not pkcs7.type_is_signedAndEnveloped()
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003308
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003309 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003310 """
Alex Chanb00ede22017-01-30 07:24:40 +00003311 `PKCS7.type_is_data` returns `False` if the PKCS7 object is not of
3312 the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003313 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003314 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003315 assert not pkcs7.type_is_data()
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003316
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003317 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003318 """
Alex Chanb00ede22017-01-30 07:24:40 +00003319 `PKCS7.get_type_name` returns a `str` giving the
Alex Gaynor791212d2015-09-05 15:46:08 -04003320 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003321 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003322 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Gaynor03737182020-07-23 20:40:46 -04003323 assert pkcs7.get_type_name() == b"pkcs7-signedData"
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003324
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003325 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003326 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003327 If an attribute other than one of the methods tested here is accessed
Alex Chanb00ede22017-01-30 07:24:40 +00003328 on an instance of `PKCS7`, `AttributeError` is raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003329 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003330 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Chanb00ede22017-01-30 07:24:40 +00003331 with pytest.raises(AttributeError):
3332 pkcs7.foo
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003333
3334
Alex Chanb00ede22017-01-30 07:24:40 +00003335class TestNetscapeSPKI(_PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003336 """
Alex Chanb00ede22017-01-30 07:24:40 +00003337 Tests for `OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003338 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003339
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003340 def signable(self):
3341 """
Alex Chanb00ede22017-01-30 07:24:40 +00003342 Return a new `NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003343 """
3344 return NetscapeSPKI()
3345
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003346 def test_type(self):
3347 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05003348 `NetscapeSPKI` can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003349 """
Alex Gaynor03737182020-07-23 20:40:46 -04003350 assert is_consistent_type(NetscapeSPKI, "NetscapeSPKI")
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003351
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003352 def test_construction(self):
3353 """
Alex Gaynor01f90a12019-02-07 09:14:48 -05003354 `NetscapeSPKI` returns an instance of `NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003355 """
3356 nspki = NetscapeSPKI()
Alex Gaynor01f90a12019-02-07 09:14:48 -05003357 assert isinstance(nspki, NetscapeSPKI)
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003358
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003359 def test_invalid_attribute(self):
3360 """
Alex Chanb00ede22017-01-30 07:24:40 +00003361 Accessing a non-existent attribute of a `NetscapeSPKI` instance
3362 causes an `AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003363 """
3364 nspki = NetscapeSPKI()
Alex Chanb00ede22017-01-30 07:24:40 +00003365 with pytest.raises(AttributeError):
3366 nspki.foo
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003367
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003368 def test_b64_encode(self):
3369 """
Alex Chanb00ede22017-01-30 07:24:40 +00003370 `NetscapeSPKI.b64_encode` encodes the certificate to a base64 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003371 """
3372 nspki = NetscapeSPKI()
3373 blob = nspki.b64_encode()
Alex Gaynor12576002019-11-18 00:18:50 -05003374 assert isinstance(blob, bytes)
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003375
3376
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003377class TestRevoked(object):
3378 """
Alex Chandeec9342016-12-19 22:00:38 +00003379 Tests for `OpenSSL.crypto.Revoked`.
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003380 """
Alex Gaynor03737182020-07-23 20:40:46 -04003381
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003382 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3383 """
3384 The get_reason method on the Revoked class checks to see if the
3385 extension is NID_crl_reason and should skip it otherwise. This test
3386 loads a CRL with extensions it should ignore.
3387 """
3388 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3389 revoked = crl.get_revoked()
3390 reason = revoked[1].get_reason()
Alex Gaynor03737182020-07-23 20:40:46 -04003391 assert reason == b"Unspecified"
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003392
3393 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3394 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3395 revoked = crl.get_revoked()
3396 revoked[1].set_reason(None)
3397 reason = revoked[1].get_reason()
3398 assert reason is None
3399
Rick Dean536ba022009-07-24 23:57:27 -05003400 def test_construction(self):
3401 """
Alex Chandeec9342016-12-19 22:00:38 +00003402 Confirm we can create `OpenSSL.crypto.Revoked`. Check that it is
3403 empty.
Rick Dean536ba022009-07-24 23:57:27 -05003404 """
3405 revoked = Revoked()
Alex Chandeec9342016-12-19 22:00:38 +00003406 assert isinstance(revoked, Revoked)
3407 assert type(revoked) == Revoked
Alex Gaynor03737182020-07-23 20:40:46 -04003408 assert revoked.get_serial() == b"00"
Alex Chandeec9342016-12-19 22:00:38 +00003409 assert revoked.get_rev_date() is None
3410 assert revoked.get_reason() is None
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003411
Rick Dean536ba022009-07-24 23:57:27 -05003412 def test_serial(self):
3413 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003414 Confirm we can set and get serial numbers from
Alex Chandeec9342016-12-19 22:00:38 +00003415 `OpenSSL.crypto.Revoked`. Confirm errors are handled with grace.
Rick Dean536ba022009-07-24 23:57:27 -05003416 """
3417 revoked = Revoked()
Alex Gaynor03737182020-07-23 20:40:46 -04003418 ret = revoked.set_serial(b"10b")
Alex Chandeec9342016-12-19 22:00:38 +00003419 assert ret is None
Rick Dean536ba022009-07-24 23:57:27 -05003420 ser = revoked.get_serial()
Alex Gaynor03737182020-07-23 20:40:46 -04003421 assert ser == b"010B"
Rick Dean536ba022009-07-24 23:57:27 -05003422
Alex Gaynor03737182020-07-23 20:40:46 -04003423 revoked.set_serial(b"31ppp") # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003424 ser = revoked.get_serial()
Alex Gaynor03737182020-07-23 20:40:46 -04003425 assert ser == b"31"
Rick Dean536ba022009-07-24 23:57:27 -05003426
Alex Chandeec9342016-12-19 22:00:38 +00003427 with pytest.raises(ValueError):
Alex Gaynor03737182020-07-23 20:40:46 -04003428 revoked.set_serial(b"pqrst")
Alex Chandeec9342016-12-19 22:00:38 +00003429 with pytest.raises(TypeError):
3430 revoked.set_serial(100)
Rick Dean536ba022009-07-24 23:57:27 -05003431
Rick Dean536ba022009-07-24 23:57:27 -05003432 def test_date(self):
3433 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003434 Confirm we can set and get revocation dates from
Alex Chandeec9342016-12-19 22:00:38 +00003435 `OpenSSL.crypto.Revoked`. Confirm errors are handled with grace.
Rick Dean536ba022009-07-24 23:57:27 -05003436 """
3437 revoked = Revoked()
3438 date = revoked.get_rev_date()
Alex Chandeec9342016-12-19 22:00:38 +00003439 assert date is None
Rick Dean536ba022009-07-24 23:57:27 -05003440
Alex Gaynore7f51982016-09-11 11:48:14 -04003441 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003442 ret = revoked.set_rev_date(now)
Alex Chandeec9342016-12-19 22:00:38 +00003443 assert ret is None
Rick Dean536ba022009-07-24 23:57:27 -05003444 date = revoked.get_rev_date()
Alex Chandeec9342016-12-19 22:00:38 +00003445 assert date == now
Rick Dean536ba022009-07-24 23:57:27 -05003446
Rick Dean6385faf2009-07-26 00:07:47 -05003447 def test_reason(self):
3448 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003449 Confirm we can set and get revocation reasons from
Alex Chandeec9342016-12-19 22:00:38 +00003450 `OpenSSL.crypto.Revoked`. The "get" need to work as "set".
3451 Likewise, each reason of all_reasons() must work.
Rick Dean6385faf2009-07-26 00:07:47 -05003452 """
3453 revoked = Revoked()
3454 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003455 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003456 ret = revoked.set_reason(r)
Alex Chandeec9342016-12-19 22:00:38 +00003457 assert ret is None
Rick Dean6385faf2009-07-26 00:07:47 -05003458 reason = revoked.get_reason()
Alex Gaynor03737182020-07-23 20:40:46 -04003459 assert reason.lower().replace(b" ", b"") == r.lower().replace(
3460 b" ", b""
3461 )
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003462 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003463
3464 revoked.set_reason(None)
Alex Chandeec9342016-12-19 22:00:38 +00003465 assert revoked.get_reason() is None
Rick Dean6385faf2009-07-26 00:07:47 -05003466
Alex Gaynor03737182020-07-23 20:40:46 -04003467 @pytest.mark.parametrize("reason", [object(), 1.0, u"foo"])
Alex Chanfb078d82017-04-20 11:16:15 +01003468 def test_set_reason_wrong_args(self, reason):
3469 """
3470 `Revoked.set_reason` raises `TypeError` if called with an argument
3471 which is neither `None` nor a byte string.
3472 """
3473 revoked = Revoked()
3474 with pytest.raises(TypeError):
3475 revoked.set_reason(reason)
3476
Alex Chandeec9342016-12-19 22:00:38 +00003477 def test_set_reason_invalid_reason(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003478 """
Alex Chandeec9342016-12-19 22:00:38 +00003479 Calling `OpenSSL.crypto.Revoked.set_reason` with an argument which
3480 isn't a valid reason results in `ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003481 """
3482 revoked = Revoked()
Alex Chandeec9342016-12-19 22:00:38 +00003483 with pytest.raises(ValueError):
Alex Gaynor03737182020-07-23 20:40:46 -04003484 revoked.set_reason(b"blue")
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003485
3486
Alex Chan7be83a52017-01-24 15:19:29 +00003487class TestCRL(object):
Rick Dean536ba022009-07-24 23:57:27 -05003488 """
Alex Chan7be83a52017-01-24 15:19:29 +00003489 Tests for `OpenSSL.crypto.CRL`.
Rick Dean536ba022009-07-24 23:57:27 -05003490 """
Alex Gaynor03737182020-07-23 20:40:46 -04003491
Paul Kehrerbeaf9f52020-08-03 17:50:31 -05003492 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3493 pkey = load_privatekey(FILETYPE_PEM, root_key_pem)
Rick Dean536ba022009-07-24 23:57:27 -05003494
Dan Sully44e767a2016-06-04 18:05:27 -07003495 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3496 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3497 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3498 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3499 intermediate_server_cert = load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04003500 FILETYPE_PEM, intermediate_server_cert_pem
3501 )
Dan Sully44e767a2016-06-04 18:05:27 -07003502 intermediate_server_key = load_privatekey(
Alex Gaynor03737182020-07-23 20:40:46 -04003503 FILETYPE_PEM, intermediate_server_key_pem
3504 )
Dan Sully44e767a2016-06-04 18:05:27 -07003505
Rick Dean536ba022009-07-24 23:57:27 -05003506 def test_construction(self):
3507 """
Alex Chan7be83a52017-01-24 15:19:29 +00003508 Confirm we can create `OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003509 that it is empty
3510 """
3511 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003512 assert isinstance(crl, CRL)
3513 assert crl.get_revoked() is None
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003514
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003515 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003516 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003517 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003518 """
3519 crl = CRL()
3520 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003521 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003522 revoked.set_rev_date(now)
Alex Gaynor03737182020-07-23 20:40:46 -04003523 revoked.set_serial(b"3ab")
3524 revoked.set_reason(b"sUpErSeDEd")
Rick Dean536ba022009-07-24 23:57:27 -05003525 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003526 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003527
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003528 def test_export_pem(self):
3529 """
3530 If not passed a format, ``CRL.export`` returns a "PEM" format string
3531 representing a serial number, a revoked reason, and certificate issuer
3532 information.
3533 """
Rick Dean536ba022009-07-24 23:57:27 -05003534 # PEM format
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003535 dumped_crl = self._get_crl().export(
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003536 self.cert, self.pkey, days=20, digest=b"sha256"
3537 )
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003538 crl = x509.load_pem_x509_crl(dumped_crl, backend)
3539 revoked = crl.get_revoked_certificate_by_serial_number(0x03AB)
3540 assert revoked is not None
Alex Gaynor03737182020-07-23 20:40:46 -04003541 assert crl.issuer == x509.Name(
3542 [
3543 x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
3544 x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
3545 x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
3546 x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
3547 x509.NameAttribute(
3548 x509.NameOID.COMMON_NAME, u"Testing Root CA"
3549 ),
3550 ]
3551 )
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003552
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003553 def test_export_der(self):
3554 """
3555 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3556 "DER" format string representing a serial number, a revoked reason, and
3557 certificate issuer information.
3558 """
3559 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003560
3561 # DER format
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003562 dumped_crl = self._get_crl().export(
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003563 self.cert, self.pkey, FILETYPE_ASN1, digest=b"md5"
3564 )
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06003565 crl = x509.load_der_x509_crl(dumped_crl, backend)
3566 revoked = crl.get_revoked_certificate_by_serial_number(0x03AB)
3567 assert revoked is not None
Alex Gaynor03737182020-07-23 20:40:46 -04003568 assert crl.issuer == x509.Name(
3569 [
3570 x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u"US"),
3571 x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, u"IL"),
3572 x509.NameAttribute(x509.NameOID.LOCALITY_NAME, u"Chicago"),
3573 x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, u"Testing"),
3574 x509.NameAttribute(
3575 x509.NameOID.COMMON_NAME, u"Testing Root CA"
3576 ),
3577 ]
3578 )
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003579
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003580 def test_export_text(self):
3581 """
3582 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3583 text format string like the one produced by the openssl command line
3584 tool.
3585 """
3586 crl = self._get_crl()
3587
Rick Dean536ba022009-07-24 23:57:27 -05003588 # text format
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003589 dumped_text = crl.export(
3590 self.cert, self.pkey, type=FILETYPE_TEXT, digest=b"md5"
3591 )
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05003592 assert len(dumped_text) > 500
Rick Dean536ba022009-07-24 23:57:27 -05003593
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003594 def test_export_custom_digest(self):
3595 """
3596 If passed the name of a digest function, ``CRL.export`` uses a
3597 signature algorithm based on that digest function.
3598 """
3599 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003600 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003601 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynor03737182020-07-23 20:40:46 -04003602 text.index(b"Signature Algorithm: sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003603
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003604 def test_export_md5_digest(self):
3605 """
3606 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3607 not emit a deprecation warning.
3608 """
3609 crl = self._get_crl()
Alex Chan7be83a52017-01-24 15:19:29 +00003610 with pytest.warns(None) as catcher:
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003611 simplefilter("always")
Alex Chan7be83a52017-01-24 15:19:29 +00003612 assert 0 == len(catcher)
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003613 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3614 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynor03737182020-07-23 20:40:46 -04003615 text.index(b"Signature Algorithm: md5")
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003616
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003617 def test_export_default_digest(self):
3618 """
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003619 If not passed the name of a digest function, ``CRL.export`` raises a
3620 ``TypeError``.
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003621 """
3622 crl = self._get_crl()
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003623 with pytest.raises(TypeError):
3624 crl.export(self.cert, self.pkey)
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003625
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003626 def test_export_invalid(self):
3627 """
Alex Chan7be83a52017-01-24 15:19:29 +00003628 If `CRL.export` is used with an uninitialized `X509` instance,
3629 `OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003630 """
3631 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003632 with pytest.raises(Error):
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003633 crl.export(X509(), PKey(), digest=b"sha256")
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003634
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003635 def test_add_revoked_keyword(self):
3636 """
Alex Chan7be83a52017-01-24 15:19:29 +00003637 `OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003638 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003639 """
3640 crl = CRL()
3641 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003642 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003643 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003644 crl.add_revoked(revoked=revoked)
Alex Chan7be83a52017-01-24 15:19:29 +00003645 assert isinstance(crl.get_revoked()[0], Revoked)
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003646
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003647 def test_export_wrong_args(self):
3648 """
Alex Chan7be83a52017-01-24 15:19:29 +00003649 Calling `OpenSSL.CRL.export` with arguments other than the certificate,
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003650 private key, integer file type, and integer number of days it
Alex Chan7be83a52017-01-24 15:19:29 +00003651 expects, results in a `TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003652 """
3653 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003654 with pytest.raises(TypeError):
3655 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3656 with pytest.raises(TypeError):
3657 crl.export(self.cert, None, FILETYPE_PEM, 10)
3658 with pytest.raises(TypeError):
3659 crl.export(self.cert, self.pkey, None, 10)
Alex Chan7be83a52017-01-24 15:19:29 +00003660 with pytest.raises(TypeError):
3661 crl.export(self.cert, FILETYPE_PEM, None)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003662
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003663 def test_export_unknown_filetype(self):
3664 """
Alex Chan7be83a52017-01-24 15:19:29 +00003665 Calling `OpenSSL.CRL.export` with a file type other than
3666 `FILETYPE_PEM`, `FILETYPE_ASN1`, or
3667 `FILETYPE_TEXT` results in a `ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003668 """
3669 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003670 with pytest.raises(ValueError):
Alex Gaynor173e4ba2017-06-30 08:01:12 -07003671 crl.export(self.cert, self.pkey, 100, 10, digest=b"sha256")
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003672
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003673 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003674 """
Alex Chan7be83a52017-01-24 15:19:29 +00003675 Calling `OpenSSL.CRL.export` with an unsupported digest results
3676 in a `ValueError` being raised.
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003677 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003678 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003679 with pytest.raises(ValueError):
3680 crl.export(
Alex Gaynor03737182020-07-23 20:40:46 -04003681 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3682 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003683
Rick Dean536ba022009-07-24 23:57:27 -05003684 def test_get_revoked(self):
3685 """
Alex Chan7be83a52017-01-24 15:19:29 +00003686 Use python to create a simple CRL with two revocations. Get back the
3687 `Revoked` using `OpenSSL.CRL.get_revoked` and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003688 """
3689 crl = CRL()
3690
3691 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003692 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003693 revoked.set_rev_date(now)
Alex Gaynor03737182020-07-23 20:40:46 -04003694 revoked.set_serial(b"3ab")
Rick Dean536ba022009-07-24 23:57:27 -05003695 crl.add_revoked(revoked)
Alex Gaynor03737182020-07-23 20:40:46 -04003696 revoked.set_serial(b"100")
3697 revoked.set_reason(b"sUpErSeDEd")
Rick Dean536ba022009-07-24 23:57:27 -05003698 crl.add_revoked(revoked)
3699
3700 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003701 assert len(revs) == 2
3702 assert type(revs[0]) == Revoked
3703 assert type(revs[1]) == Revoked
Alex Gaynor03737182020-07-23 20:40:46 -04003704 assert revs[0].get_serial() == b"03AB"
3705 assert revs[1].get_serial() == b"0100"
Alex Chan7be83a52017-01-24 15:19:29 +00003706 assert revs[0].get_rev_date() == now
3707 assert revs[1].get_rev_date() == now
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003708
Rick Dean536ba022009-07-24 23:57:27 -05003709 def test_load_crl(self):
3710 """
Alex Chan7be83a52017-01-24 15:19:29 +00003711 Load a known CRL and inspect its revocations. Both EM and DER formats
3712 are loaded.
Rick Dean536ba022009-07-24 23:57:27 -05003713 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003714 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003715 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003716 assert len(revs) == 2
Alex Gaynor03737182020-07-23 20:40:46 -04003717 assert revs[0].get_serial() == b"03AB"
Alex Chan7be83a52017-01-24 15:19:29 +00003718 assert revs[0].get_reason() is None
Alex Gaynor03737182020-07-23 20:40:46 -04003719 assert revs[1].get_serial() == b"0100"
3720 assert revs[1].get_reason() == b"Superseded"
Rick Dean536ba022009-07-24 23:57:27 -05003721
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003722 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003723 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003724 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003725 assert len(revs) == 2
Alex Gaynor03737182020-07-23 20:40:46 -04003726 assert revs[0].get_serial() == b"03AB"
Alex Chan7be83a52017-01-24 15:19:29 +00003727 assert revs[0].get_reason() is None
Alex Gaynor03737182020-07-23 20:40:46 -04003728 assert revs[1].get_serial() == b"0100"
3729 assert revs[1].get_reason() == b"Superseded"
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003730
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003731 def test_load_crl_bad_filetype(self):
3732 """
Alex Chan7be83a52017-01-24 15:19:29 +00003733 Calling `OpenSSL.crypto.load_crl` with an unknown file type raises a
3734 `ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003735 """
Alex Chan7be83a52017-01-24 15:19:29 +00003736 with pytest.raises(ValueError):
3737 load_crl(100, crlData)
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003738
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003739 def test_load_crl_bad_data(self):
3740 """
Alex Chan7be83a52017-01-24 15:19:29 +00003741 Calling `OpenSSL.crypto.load_crl` with file data which can't be loaded
3742 raises a `OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003743 """
Alex Chan7be83a52017-01-24 15:19:29 +00003744 with pytest.raises(Error):
3745 load_crl(FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003746
Dan Sully44e767a2016-06-04 18:05:27 -07003747 def test_get_issuer(self):
3748 """
Alex Chan7be83a52017-01-24 15:19:29 +00003749 Load a known CRL and assert its issuer's common name is what we expect
3750 from the encoded crlData string.
Dan Sully44e767a2016-06-04 18:05:27 -07003751 """
3752 crl = load_crl(FILETYPE_PEM, crlData)
Alex Chan7be83a52017-01-24 15:19:29 +00003753 assert isinstance(crl.get_issuer(), X509Name)
Alex Gaynor03737182020-07-23 20:40:46 -04003754 assert crl.get_issuer().CN == "Testing Root CA"
Dan Sully44e767a2016-06-04 18:05:27 -07003755
Dominic Chenf05b2122015-10-13 16:32:35 +00003756 def test_dump_crl(self):
3757 """
3758 The dumped CRL matches the original input.
3759 """
3760 crl = load_crl(FILETYPE_PEM, crlData)
3761 buf = dump_crl(FILETYPE_PEM, crl)
3762 assert buf == crlData
3763
Dan Sully44e767a2016-06-04 18:05:27 -07003764 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3765 """
3766 Create a CRL.
3767
3768 :param list[X509] certs: A list of certificates to revoke.
3769 :rtype: CRL
3770 """
3771 crl = CRL()
3772 for cert in certs:
3773 revoked = Revoked()
3774 # FIXME: This string splicing is an unfortunate implementation
3775 # detail that has been reported in
3776 # https://github.com/pyca/pyopenssl/issues/258
Alex Gaynor03737182020-07-23 20:40:46 -04003777 serial = hex(cert.get_serial_number())[2:].encode("utf-8")
Dan Sully44e767a2016-06-04 18:05:27 -07003778 revoked.set_serial(serial)
Alex Gaynor03737182020-07-23 20:40:46 -04003779 revoked.set_reason(b"unspecified")
3780 revoked.set_rev_date(b"20140601000000Z")
Dan Sully44e767a2016-06-04 18:05:27 -07003781 crl.add_revoked(revoked)
3782 crl.set_version(1)
Alex Gaynor03737182020-07-23 20:40:46 -04003783 crl.set_lastUpdate(b"20140601000000Z")
3784 crl.set_nextUpdate(b"20180601000000Z")
3785 crl.sign(issuer_cert, issuer_key, digest=b"sha512")
Dan Sully44e767a2016-06-04 18:05:27 -07003786 return crl
3787
3788 def test_verify_with_revoked(self):
3789 """
Alex Chan7be83a52017-01-24 15:19:29 +00003790 `verify_certificate` raises error when an intermediate certificate is
3791 revoked.
Dan Sully44e767a2016-06-04 18:05:27 -07003792 """
3793 store = X509Store()
3794 store.add_cert(self.root_cert)
3795 store.add_cert(self.intermediate_cert)
3796 root_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003797 self.root_cert, self.root_key, certs=[self.intermediate_cert]
3798 )
Dan Sully44e767a2016-06-04 18:05:27 -07003799 intermediate_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003800 self.intermediate_cert, self.intermediate_key, certs=[]
3801 )
Dan Sully44e767a2016-06-04 18:05:27 -07003802 store.add_crl(root_crl)
3803 store.add_crl(intermediate_crl)
3804 store.set_flags(
Alex Gaynor03737182020-07-23 20:40:46 -04003805 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL
3806 )
Dan Sully44e767a2016-06-04 18:05:27 -07003807 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003808 with pytest.raises(X509StoreContextError) as err:
3809 store_ctx.verify_certificate()
Alex Gaynor03737182020-07-23 20:40:46 -04003810 assert err.value.args[0][2] == "certificate revoked"
Dan Sully44e767a2016-06-04 18:05:27 -07003811
3812 def test_verify_with_missing_crl(self):
3813 """
Alex Chan7be83a52017-01-24 15:19:29 +00003814 `verify_certificate` raises error when an intermediate certificate's
3815 CRL is missing.
Dan Sully44e767a2016-06-04 18:05:27 -07003816 """
3817 store = X509Store()
3818 store.add_cert(self.root_cert)
3819 store.add_cert(self.intermediate_cert)
3820 root_crl = self._make_test_crl(
Alex Gaynor03737182020-07-23 20:40:46 -04003821 self.root_cert, self.root_key, certs=[self.intermediate_cert]
3822 )
Dan Sully44e767a2016-06-04 18:05:27 -07003823 store.add_crl(root_crl)
3824 store.set_flags(
Alex Gaynor03737182020-07-23 20:40:46 -04003825 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL
3826 )
Dan Sully44e767a2016-06-04 18:05:27 -07003827 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003828 with pytest.raises(X509StoreContextError) as err:
3829 store_ctx.verify_certificate()
Alex Gaynor03737182020-07-23 20:40:46 -04003830 assert err.value.args[0][2] == "unable to get certificate CRL"
3831 assert err.value.certificate.get_subject().CN == "intermediate-service"
Dan Sully44e767a2016-06-04 18:05:27 -07003832
Paul Kehrer41c10242017-06-29 18:24:17 -05003833 def test_convert_from_cryptography(self):
3834 crypto_crl = x509.load_pem_x509_crl(crlData, backend)
3835 crl = CRL.from_cryptography(crypto_crl)
3836 assert isinstance(crl, CRL)
3837
3838 def test_convert_from_cryptography_unsupported_type(self):
3839 with pytest.raises(TypeError):
3840 CRL.from_cryptography(object())
3841
3842 def test_convert_to_cryptography_key(self):
3843 crl = load_crl(FILETYPE_PEM, crlData)
3844 crypto_crl = crl.to_cryptography()
3845 assert isinstance(crypto_crl, x509.CertificateRevocationList)
3846
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003847
Alex Chan7be83a52017-01-24 15:19:29 +00003848class TestX509StoreContext(object):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003849 """
Alex Chan7be83a52017-01-24 15:19:29 +00003850 Tests for `OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003851 """
Alex Gaynor03737182020-07-23 20:40:46 -04003852
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003853 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3854 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003855 intermediate_server_cert = load_certificate(
Alex Gaynor03737182020-07-23 20:40:46 -04003856 FILETYPE_PEM, intermediate_server_cert_pem
3857 )
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003858
3859 def test_valid(self):
3860 """
Alex Chan7be83a52017-01-24 15:19:29 +00003861 `verify_certificate` returns ``None`` when called with a certificate
3862 and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003863 """
3864 store = X509Store()
3865 store.add_cert(self.root_cert)
3866 store.add_cert(self.intermediate_cert)
3867 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003868 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003869
3870 def test_reuse(self):
3871 """
Alex Chan7be83a52017-01-24 15:19:29 +00003872 `verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003873 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003874 """
3875 store = X509Store()
3876 store.add_cert(self.root_cert)
3877 store.add_cert(self.intermediate_cert)
3878 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003879 assert store_ctx.verify_certificate() is None
3880 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003881
Sándor Oroszi83ef2302020-10-12 15:42:23 +02003882 @pytest.mark.parametrize(
3883 "root_cert, chain, verified_cert",
3884 [
3885 pytest.param(
3886 root_cert,
3887 [intermediate_cert],
3888 intermediate_server_cert,
3889 id="intermediate in chain",
3890 ),
3891 pytest.param(
3892 root_cert,
3893 [],
3894 intermediate_cert,
3895 id="empty chain",
3896 ),
3897 pytest.param(
3898 root_cert,
3899 [root_cert, intermediate_server_cert, intermediate_cert],
3900 intermediate_server_cert,
3901 id="extra certs in chain",
3902 ),
3903 ],
3904 )
3905 def test_verify_success_with_chain(self, root_cert, chain, verified_cert):
3906 store = X509Store()
3907 store.add_cert(root_cert)
3908 store_ctx = X509StoreContext(store, verified_cert, chain=chain)
3909 assert store_ctx.verify_certificate() is None
3910
3911 def test_valid_untrusted_chain_reuse(self):
3912 """
3913 `verify_certificate` using an untrusted chain can be called multiple
3914 times with the same ``X509StoreContext`` instance to produce the same
3915 result.
3916 """
3917 store = X509Store()
3918 store.add_cert(self.root_cert)
3919 chain = [self.intermediate_cert]
3920
3921 store_ctx = X509StoreContext(
3922 store, self.intermediate_server_cert, chain=chain
3923 )
3924 assert store_ctx.verify_certificate() is None
3925 assert store_ctx.verify_certificate() is None
3926
3927 def test_chain_reference(self):
3928 """
3929 ``X509StoreContext`` properly keeps references to the untrusted chain
3930 certificates.
3931 """
3932 store = X509Store()
3933 store.add_cert(self.root_cert)
3934 chain = [load_certificate(FILETYPE_PEM, intermediate_cert_pem)]
3935
3936 store_ctx = X509StoreContext(
3937 store, self.intermediate_server_cert, chain=chain
3938 )
3939
3940 del chain
3941 assert store_ctx.verify_certificate() is None
3942
3943 @pytest.mark.parametrize(
3944 "root_cert, chain, verified_cert",
3945 [
3946 pytest.param(
3947 root_cert,
3948 [],
3949 intermediate_server_cert,
3950 id="intermediate missing",
3951 ),
3952 pytest.param(
3953 None,
3954 [intermediate_cert],
3955 intermediate_server_cert,
3956 id="no trusted root",
3957 ),
3958 pytest.param(
3959 None,
3960 [root_cert, intermediate_cert],
3961 intermediate_server_cert,
3962 id="untrusted root, full chain is available",
3963 ),
3964 pytest.param(
3965 intermediate_cert,
3966 [root_cert, intermediate_cert],
3967 intermediate_server_cert,
3968 id="untrusted root, intermediate is trusted and in chain",
3969 ),
3970 ],
3971 )
3972 def test_verify_fail_with_chain(self, root_cert, chain, verified_cert):
3973 store = X509Store()
3974 if root_cert:
3975 store.add_cert(root_cert)
3976
3977 store_ctx = X509StoreContext(store, verified_cert, chain=chain)
3978
3979 with pytest.raises(X509StoreContextError):
3980 store_ctx.verify_certificate()
3981
3982 @pytest.mark.parametrize(
3983 "chain, expected_error",
3984 [
3985 pytest.param(
3986 [intermediate_cert, "This is not a certificate"],
3987 TypeError,
3988 id="non-certificate in chain",
3989 ),
3990 pytest.param(
3991 42,
3992 TypeError,
3993 id="non-list chain",
3994 ),
3995 ],
3996 )
3997 def test_untrusted_chain_wrong_args(self, chain, expected_error):
3998 """
3999 Creating ``X509StoreContext`` with wrong chain raises an exception.
4000 """
4001 store = X509Store()
4002 store.add_cert(self.root_cert)
4003
4004 with pytest.raises(expected_error):
4005 X509StoreContext(store, self.intermediate_server_cert, chain=chain)
4006
4007 def test_failure_building_untrusted_chain_raises(self, monkeypatch):
4008 """
4009 Creating ``X509StoreContext`` raises ``OpenSSL.crypto.Error`` when
4010 the underlying lib fails to add the certificate to the stack.
4011 """
4012 monkeypatch.setattr(_lib, "sk_X509_push", lambda _stack, _x509: -1)
4013
4014 store = X509Store()
4015 store.add_cert(self.root_cert)
4016 chain = [self.intermediate_cert]
4017
4018 with pytest.raises(Error):
4019 X509StoreContext(store, self.intermediate_server_cert, chain=chain)
4020
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004021 def test_trusted_self_signed(self):
4022 """
Alex Chan7be83a52017-01-24 15:19:29 +00004023 `verify_certificate` returns ``None`` when called with a self-signed
4024 certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004025 """
4026 store = X509Store()
4027 store.add_cert(self.root_cert)
4028 store_ctx = X509StoreContext(store, self.root_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00004029 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004030
4031 def test_untrusted_self_signed(self):
4032 """
Alex Chan7be83a52017-01-24 15:19:29 +00004033 `verify_certificate` raises error when a self-signed certificate is
4034 verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004035 """
4036 store = X509Store()
4037 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04004038 with pytest.raises(X509StoreContextError) as exc:
4039 store_ctx.verify_certificate()
4040
Alex Gaynor03737182020-07-23 20:40:46 -04004041 assert exc.value.args[0][2] == "self signed certificate"
4042 assert exc.value.certificate.get_subject().CN == "Testing Root CA"
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05004043
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004044 def test_invalid_chain_no_root(self):
4045 """
Alex Chan7be83a52017-01-24 15:19:29 +00004046 `verify_certificate` raises error when a root certificate is missing
4047 from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004048 """
4049 store = X509Store()
4050 store.add_cert(self.intermediate_cert)
4051 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04004052
4053 with pytest.raises(X509StoreContextError) as exc:
4054 store_ctx.verify_certificate()
4055
Alex Gaynor03737182020-07-23 20:40:46 -04004056 assert exc.value.args[0][2] == "unable to get issuer certificate"
4057 assert exc.value.certificate.get_subject().CN == "intermediate"
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05004058
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004059 def test_invalid_chain_no_intermediate(self):
4060 """
Alex Chan7be83a52017-01-24 15:19:29 +00004061 `verify_certificate` raises error when an intermediate certificate is
4062 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004063 """
4064 store = X509Store()
4065 store.add_cert(self.root_cert)
4066 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05004067
Alex Gaynor85b49702015-09-05 16:30:59 -04004068 with pytest.raises(X509StoreContextError) as exc:
4069 store_ctx.verify_certificate()
4070
Alex Gaynor03737182020-07-23 20:40:46 -04004071 assert exc.value.args[0][2] == "unable to get local issuer certificate"
4072 assert exc.value.certificate.get_subject().CN == "intermediate-service"
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07004073
Stephen Holsapple46a09252015-02-12 14:45:43 -08004074 def test_modification_pre_verify(self):
4075 """
Alex Chan7be83a52017-01-24 15:19:29 +00004076 `verify_certificate` can use a store context modified after
Stephen Holsapple46a09252015-02-12 14:45:43 -08004077 instantiation.
4078 """
4079 store_bad = X509Store()
4080 store_bad.add_cert(self.intermediate_cert)
4081 store_good = X509Store()
4082 store_good.add_cert(self.root_cert)
4083 store_good.add_cert(self.intermediate_cert)
4084 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04004085
4086 with pytest.raises(X509StoreContextError) as exc:
4087 store_ctx.verify_certificate()
4088
Alex Gaynor03737182020-07-23 20:40:46 -04004089 assert exc.value.args[0][2] == "unable to get issuer certificate"
4090 assert exc.value.certificate.get_subject().CN == "intermediate"
Alex Gaynor85b49702015-09-05 16:30:59 -04004091
Stephen Holsapple46a09252015-02-12 14:45:43 -08004092 store_ctx.set_store(store_good)
Alex Chan7be83a52017-01-24 15:19:29 +00004093 assert store_ctx.verify_certificate() is None
Stephen Holsapple46a09252015-02-12 14:45:43 -08004094
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004095 def test_verify_with_time(self):
4096 """
4097 `verify_certificate` raises error when the verification time is
4098 set at notAfter.
4099 """
4100 store = X509Store()
4101 store.add_cert(self.root_cert)
4102 store.add_cert(self.intermediate_cert)
4103
4104 expire_time = self.intermediate_server_cert.get_notAfter()
4105 expire_datetime = datetime.strptime(
Alex Gaynor03737182020-07-23 20:40:46 -04004106 expire_time.decode("utf-8"), "%Y%m%d%H%M%SZ"
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004107 )
4108 store.set_time(expire_datetime)
4109
4110 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4111 with pytest.raises(X509StoreContextError) as exc:
4112 store_ctx.verify_certificate()
4113
Alex Gaynor03737182020-07-23 20:40:46 -04004114 assert exc.value.args[0][2] == "certificate has expired"
Thomas Sileoe15e60a2016-11-22 18:13:30 +01004115
Shane Harvey33c54992020-08-05 16:48:51 -07004116 def test_get_verified_chain(self):
4117 """
4118 `get_verified_chain` returns the verified chain.
4119 """
4120 store = X509Store()
4121 store.add_cert(self.root_cert)
4122 store.add_cert(self.intermediate_cert)
4123 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4124 chain = store_ctx.get_verified_chain()
4125 assert len(chain) == 3
4126 intermediate_subject = self.intermediate_server_cert.get_subject()
4127 assert chain[0].get_subject() == intermediate_subject
4128 assert chain[1].get_subject() == self.intermediate_cert.get_subject()
4129 assert chain[2].get_subject() == self.root_cert.get_subject()
4130 # Test reuse
4131 chain = store_ctx.get_verified_chain()
4132 assert len(chain) == 3
4133 assert chain[0].get_subject() == intermediate_subject
4134 assert chain[1].get_subject() == self.intermediate_cert.get_subject()
4135 assert chain[2].get_subject() == self.root_cert.get_subject()
4136
4137 def test_get_verified_chain_invalid_chain_no_root(self):
4138 """
4139 `get_verified_chain` raises error when cert verification fails.
4140 """
4141 store = X509Store()
4142 store.add_cert(self.intermediate_cert)
4143 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4144
4145 with pytest.raises(X509StoreContextError) as exc:
4146 store_ctx.get_verified_chain()
4147
4148 assert exc.value.args[0][2] == "unable to get issuer certificate"
4149 assert exc.value.certificate.get_subject().CN == "intermediate"
4150
Sándor Oroszi43c97762020-09-11 17:17:31 +02004151 @pytest.fixture
4152 def root_ca_file(self, tmpdir):
4153 return self._create_ca_file(tmpdir, "root_ca_hash_dir", self.root_cert)
4154
4155 @pytest.fixture
4156 def intermediate_ca_file(self, tmpdir):
4157 return self._create_ca_file(
4158 tmpdir, "intermediate_ca_hash_dir", self.intermediate_cert
4159 )
4160
4161 @staticmethod
4162 def _create_ca_file(base_path, hash_directory, cacert):
4163 ca_hash = "{:08x}.0".format(cacert.subject_name_hash())
4164 cafile = base_path.join(hash_directory, ca_hash)
4165 cafile.write_binary(
4166 dump_certificate(FILETYPE_PEM, cacert), ensure=True
4167 )
4168 return cafile
4169
4170 def test_verify_with_ca_file_location(self, root_ca_file):
4171 store = X509Store()
4172 store.load_locations(str(root_ca_file))
4173
4174 store_ctx = X509StoreContext(store, self.intermediate_cert)
4175 store_ctx.verify_certificate()
4176
4177 def test_verify_with_ca_path_location(self, root_ca_file):
4178 store = X509Store()
4179 store.load_locations(None, str(root_ca_file.dirname))
4180
4181 store_ctx = X509StoreContext(store, self.intermediate_cert)
4182 store_ctx.verify_certificate()
4183
4184 def test_verify_with_cafile_and_capath(
4185 self, root_ca_file, intermediate_ca_file
4186 ):
4187 store = X509Store()
4188 store.load_locations(
4189 cafile=str(root_ca_file), capath=str(intermediate_ca_file.dirname)
4190 )
4191
4192 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4193 store_ctx.verify_certificate()
4194
4195 def test_verify_with_multiple_ca_files(
4196 self, root_ca_file, intermediate_ca_file
4197 ):
4198 store = X509Store()
4199 store.load_locations(str(root_ca_file))
4200 store.load_locations(str(intermediate_ca_file))
4201
4202 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
4203 store_ctx.verify_certificate()
4204
4205 def test_verify_failure_with_empty_ca_directory(self, tmpdir):
4206 store = X509Store()
4207 store.load_locations(None, str(tmpdir))
4208
4209 store_ctx = X509StoreContext(store, self.intermediate_cert)
4210 with pytest.raises(X509StoreContextError) as exc:
4211 store_ctx.verify_certificate()
4212
4213 assert exc.value.args[0][2] == "unable to get local issuer certificate"
4214
Stephen Holsapple46a09252015-02-12 14:45:43 -08004215
Alex Chan7be83a52017-01-24 15:19:29 +00004216class TestSignVerify(object):
James Yonan7c2e5d32010-02-27 05:45:50 -07004217 """
Alex Chan7be83a52017-01-24 15:19:29 +00004218 Tests for `OpenSSL.crypto.sign` and `OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07004219 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004220
James Yonan7c2e5d32010-02-27 05:45:50 -07004221 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004222 """
Alex Chan7be83a52017-01-24 15:19:29 +00004223 `sign` generates a cryptographic signature which `verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004224 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004225 content = (
4226 b"It was a bright cold day in April, and the clocks were striking "
4227 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4228 b"effort to escape the vile wind, slipped quickly through the "
4229 b"glass doors of Victory Mansions, though not quickly enough to "
Alex Gaynor03737182020-07-23 20:40:46 -04004230 b"prevent a swirl of gritty dust from entering along with him."
4231 )
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04004232
4233 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04004234 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04004235 # verify the content with this cert
4236 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
4237 # certificate unrelated to priv_key, used to trigger an error
4238 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07004239
Alex Gaynor03737182020-07-23 20:40:46 -04004240 for digest in ["md5", "sha1"]:
James Yonan7c2e5d32010-02-27 05:45:50 -07004241 sig = sign(priv_key, content, digest)
4242
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004243 # Verify the signature of content, will throw an exception if
4244 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07004245 verify(good_cert, sig, content, digest)
4246
4247 # This should fail because the certificate doesn't match the
4248 # private key that was used to sign the content.
Alex Chan7be83a52017-01-24 15:19:29 +00004249 with pytest.raises(Error):
4250 verify(bad_cert, sig, content, digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07004251
4252 # This should fail because we've "tainted" the content after
4253 # signing it.
Alex Chan7be83a52017-01-24 15:19:29 +00004254 with pytest.raises(Error):
4255 verify(good_cert, sig, content + b"tainted", digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07004256
4257 # test that unknown digest types fail
Alex Chan7be83a52017-01-24 15:19:29 +00004258 with pytest.raises(ValueError):
4259 sign(priv_key, content, "strange-digest")
4260 with pytest.raises(ValueError):
4261 verify(good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07004262
Abraham Martinc5484ba2015-03-25 15:33:05 +00004263 def test_sign_verify_with_text(self):
4264 """
Alex Chan7be83a52017-01-24 15:19:29 +00004265 `sign` generates a cryptographic signature which
4266 `verify` can check. Deprecation warnings raised because using
Alex Gaynor791212d2015-09-05 15:46:08 -04004267 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00004268 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04004269 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04004270 b"It was a bright cold day in April, and the clocks were striking "
4271 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4272 b"effort to escape the vile wind, slipped quickly through the "
4273 b"glass doors of Victory Mansions, though not quickly enough to "
4274 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04004275 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00004276
4277 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
4278 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Alex Gaynor03737182020-07-23 20:40:46 -04004279 for digest in ["md5", "sha1"]:
Alex Chan7be83a52017-01-24 15:19:29 +00004280 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00004281 simplefilter("always")
4282 sig = sign(priv_key, content, digest)
Alex Gaynor03737182020-07-23 20:40:46 -04004283 assert "{0} for data is no longer accepted, use bytes".format(
4284 WARNING_TYPE_EXPECTED
4285 ) == str(w[-1].message)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04004286
Alex Chan7be83a52017-01-24 15:19:29 +00004287 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00004288 simplefilter("always")
4289 verify(cert, sig, content, digest)
Alex Gaynor03737182020-07-23 20:40:46 -04004290 assert "{0} for data is no longer accepted, use bytes".format(
4291 WARNING_TYPE_EXPECTED
4292 ) == str(w[-1].message)
Abraham Martinc5484ba2015-03-25 15:33:05 +00004293
Paul Kehrer59d26252017-07-20 10:45:54 +02004294 def test_sign_verify_ecdsa(self):
4295 """
4296 `sign` generates a cryptographic signature which `verify` can check.
4297 ECDSA Signatures in the X9.62 format may have variable length,
4298 different from the length of the private key.
4299 """
4300 content = (
4301 b"It was a bright cold day in April, and the clocks were striking "
4302 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4303 b"effort to escape the vile wind, slipped quickly through the "
4304 b"glass doors of Victory Mansions, though not quickly enough to "
4305 b"prevent a swirl of gritty dust from entering along with him."
Paul Kehrerc45a6ea2020-08-03 15:54:20 -05004306 )
Paul Kehrer59d26252017-07-20 10:45:54 +02004307 priv_key = load_privatekey(FILETYPE_PEM, ec_root_key_pem)
4308 cert = load_certificate(FILETYPE_PEM, ec_root_cert_pem)
4309 sig = sign(priv_key, content, "sha1")
4310 verify(cert, sig, content, "sha1")
4311
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004312 def test_sign_nulls(self):
4313 """
Alex Chan7be83a52017-01-24 15:19:29 +00004314 `sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004315 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004316 content = b"Watch out! \0 Did you see it?"
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004317 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
4318 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
4319 sig = sign(priv_key, content, "sha1")
4320 verify(good_cert, sig, content, "sha1")
4321
Colleen Murphye09399b2016-03-01 17:40:49 -08004322 def test_sign_with_large_key(self):
4323 """
Alex Chan7be83a52017-01-24 15:19:29 +00004324 `sign` produces a signature for a string when using a long key.
Colleen Murphye09399b2016-03-01 17:40:49 -08004325 """
Alex Gaynore7f51982016-09-11 11:48:14 -04004326 content = (
4327 b"It was a bright cold day in April, and the clocks were striking "
4328 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
4329 b"effort to escape the vile wind, slipped quickly through the "
4330 b"glass doors of Victory Mansions, though not quickly enough to "
Alex Gaynor03737182020-07-23 20:40:46 -04004331 b"prevent a swirl of gritty dust from entering along with him."
4332 )
Colleen Murphye09399b2016-03-01 17:40:49 -08004333
4334 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
4335 sign(priv_key, content, "sha1")
4336
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05004337
Alex Chan63ef9bc2016-12-19 12:02:06 +00004338class TestEllipticCurve(object):
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004339 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004340 Tests for `_EllipticCurve`, `get_elliptic_curve`, and
4341 `get_elliptic_curves`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004342 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004343
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004344 def test_set(self):
4345 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004346 `get_elliptic_curves` returns a `set`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004347 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004348 assert isinstance(get_elliptic_curves(), set)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004349
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004350 def test_a_curve(self):
4351 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004352 `get_elliptic_curve` can be used to retrieve a particular supported
4353 curve.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004354 """
4355 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004356 curve = next(iter(curves))
4357 assert curve.name == get_elliptic_curve(curve.name).name
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004358
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004359 def test_not_a_curve(self):
4360 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004361 `get_elliptic_curve` raises `ValueError` if called with a name which
4362 does not identify a supported curve.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004363 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004364 with pytest.raises(ValueError):
4365 get_elliptic_curve(u"this curve was just invented")
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004366
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004367 def test_repr(self):
4368 """
4369 The string representation of a curve object includes simply states the
4370 object is a curve and what its name is.
4371 """
4372 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004373 curve = next(iter(curves))
4374 assert "<Curve %r>" % (curve.name,) == repr(curve)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004375
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004376 def test_to_EC_KEY(self):
4377 """
4378 The curve object can export a version of itself as an EC_KEY* via the
Alex Chan63ef9bc2016-12-19 12:02:06 +00004379 private `_EllipticCurve._to_EC_KEY`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004380 """
4381 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00004382 curve = next(iter(curves))
4383 # It's not easy to assert anything about this object. However, see
4384 # leakcheck/crypto.py for a test that demonstrates it at least does
4385 # not leak memory.
4386 curve._to_EC_KEY()
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04004387
4388
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004389class EllipticCurveFactory(object):
4390 """
4391 A helper to get the names of two curves.
4392 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04004393
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004394 def __init__(self):
4395 curves = iter(get_elliptic_curves())
Alex Chan63ef9bc2016-12-19 12:02:06 +00004396 self.curve_name = next(curves).name
4397 self.another_curve_name = next(curves).name
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004398
4399
Alex Chan63ef9bc2016-12-19 12:02:06 +00004400class TestEllipticCurveEquality(EqualityTestsMixin):
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004401 """
Paul Kehrer7d5a3bf2019-01-21 12:24:02 -06004402 Tests `_EllipticCurve`'s implementation of ``==`` and ``!=``.
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004403 """
Alex Gaynor03737182020-07-23 20:40:46 -04004404
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004405 curve_factory = EllipticCurveFactory()
4406
4407 if curve_factory.curve_name is None:
4408 skip = "There are no curves available there can be no curve objects."
4409
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004410 def anInstance(self):
4411 """
4412 Get the curve object for an arbitrary curve supported by the system.
4413 """
4414 return get_elliptic_curve(self.curve_factory.curve_name)
4415
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04004416 def anotherInstance(self):
4417 """
4418 Get the curve object for an arbitrary curve supported by the system -
4419 but not the one returned by C{anInstance}.
4420 """
4421 return get_elliptic_curve(self.curve_factory.another_curve_name)
4422
4423
Alex Chan63ef9bc2016-12-19 12:02:06 +00004424class TestEllipticCurveHash(object):
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004425 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004426 Tests for `_EllipticCurve`'s implementation of hashing (thus use as
4427 an item in a `dict` or `set`).
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004428 """
Alex Gaynor03737182020-07-23 20:40:46 -04004429
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004430 curve_factory = EllipticCurveFactory()
4431
4432 if curve_factory.curve_name is None:
4433 skip = "There are no curves available there can be no curve objects."
4434
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004435 def test_contains(self):
4436 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004437 The ``in`` operator reports that a `set` containing a curve does
4438 contain that curve.
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004439 """
4440 curve = get_elliptic_curve(self.curve_factory.curve_name)
4441 curves = set([curve])
Alex Chan63ef9bc2016-12-19 12:02:06 +00004442 assert curve in curves
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004443
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004444 def test_does_not_contain(self):
4445 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00004446 The ``in`` operator reports that a `set` not containing a curve
4447 does not contain that curve.
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04004448 """
4449 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor03737182020-07-23 20:40:46 -04004450 curves = set(
4451 [get_elliptic_curve(self.curve_factory.another_curve_name)]
4452 )
Alex Chan63ef9bc2016-12-19 12:02:06 +00004453 assert curve not in curves