blob: 10d2427008a023668ed0d18b1010cded2a25f4ea [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
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04008from unittest import main
Jean-Paul Calderone60432792015-04-13 12:26:07 -04009from warnings import catch_warnings, simplefilter
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -040010
Alex Gaynor4b9c96a2014-08-14 09:51:48 -070011import base64
12import os
13import re
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -040014from subprocess import PIPE, Popen
Rick Dean47262da2009-07-08 16:17:17 -050015from datetime import datetime, timedelta
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050016
Alex Gaynor791212d2015-09-05 15:46:08 -040017import pytest
18
Alex Gaynorb8e38992015-09-04 08:14:04 -040019from six import u, b, binary_type
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050020
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050021from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050022from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
Alex Gaynor31287502015-09-05 16:11:27 -040023from OpenSSL.crypto import (
Dan Sully44e767a2016-06-04 18:05:27 -070024 X509Store,
25 X509StoreFlags,
26 X509StoreType,
27 X509StoreContext,
28 X509StoreContextError
Alex Gaynor31287502015-09-05 16:11:27 -040029)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070030from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -050031from OpenSSL.crypto import X509Extension, X509ExtensionType
Rick Dean5b7b6372009-04-01 11:34:06 -050032from OpenSSL.crypto import load_certificate, load_privatekey
Cory Benfield6492f7c2015-10-27 16:57:58 +090033from OpenSSL.crypto import load_publickey, dump_publickey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040034from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040035from OpenSSL.crypto import dump_certificate, load_certificate_request
36from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040037from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Jean-Paul Calderone9178ee62010-01-25 17:55:30 -050038from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000039from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040040from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040041from OpenSSL.crypto import (
42 sign, verify, get_elliptic_curve, get_elliptic_curves)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020043from OpenSSL._util import native, lib
44
45from .util import (
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040046 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
47)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040048
Alex Gaynoraceb3e22015-09-05 12:00:22 -040049
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040050def normalize_certificate_pem(pem):
51 return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
52
53
54def normalize_privatekey_pem(pem):
55 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
56
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040057
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050058GOOD_CIPHER = "blowfish"
59BAD_CIPHER = "zippers"
60
Anthony Alba2ce737f2015-12-04 11:04:56 +080061GOOD_DIGEST = "SHA1"
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050062BAD_DIGEST = "monkeys"
63
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040064root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050065MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
66BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
67ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
68NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
69MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
70ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
71urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
722xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
731dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
74FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
75VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
76BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
77b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
78AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
79hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
80w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
81-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040082""")
Rick Dean94e46fd2009-07-18 14:51:24 -050083
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040084root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050085MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
86jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
873claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
88AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
89yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
906JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
91BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
92u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
93PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
94I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
95ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
966AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
97cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
98-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040099""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500100
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700101intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
102MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
103WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
104DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
105ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
106dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
107MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
108AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
109FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
11021H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
111AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
112QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1139n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1149mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
115-----END CERTIFICATE-----
116""")
117
118intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
119MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
120ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
121qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
122AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
123rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
124147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
125+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
126wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
127sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
12852vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
129DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
130/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
131NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
132-----END RSA PRIVATE KEY-----
133""")
134
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400135server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500136MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
137BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
138VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
139NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
140gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
141lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
142b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
143lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
144gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
145dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1462mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
147uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
148-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400149""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500150
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400151server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500152MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
153U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
154SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
155AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
156j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
157j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
158Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
159msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
160FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1614e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1621sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
163NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
164r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
165-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400166"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500167
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700168intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
169MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
170ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
171CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
172biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
173BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
174CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
175biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
176iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
177+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
178biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
179UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1803bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
181x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
182-----END CERTIFICATE-----
183""")
184
185intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
186MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
187SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1888Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
189AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1905ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
191d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
192z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
193dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
194EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
195X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
1969UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
197ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
198nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
199-----END RSA PRIVATE KEY-----
200""")
201
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400202client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500203MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
204BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
205VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
206ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
207MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
208rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
209iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
210oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2110fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
212Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2139Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
214PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
215-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400216""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500217
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400218client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500219MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
220btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
221eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
222AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
223zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
224h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
225V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
226TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
227dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
228D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
229si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
230JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
231f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
232-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400233"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400234
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400235cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400236MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
237BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
238ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
239NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
240MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
241ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
242urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2432xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2441dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
245FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
246VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
247BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
248b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
249AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
250hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
251w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
252-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400253""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400254
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400255cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
256-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400257MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
258jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2593claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
260AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
261yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2626JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
263BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
264u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
265PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
266I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
267ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2686AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
269cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
270-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400271"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400272
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400273cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
274MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
275EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
276ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
277BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
278E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
279xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
280gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
281Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
282oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
283-----END CERTIFICATE REQUEST-----
284""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500285
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400286encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400287Proc-Type: 4,ENCRYPTED
288DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400289
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400290SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
291a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2928+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
293mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
294+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
295fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
296tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
297rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
298gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
299o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
3007SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
301MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
30211n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
303-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400304""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400305
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400306encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400307
Cory Benfield6492f7c2015-10-27 16:57:58 +0900308
309cleartextPublicKeyPEM = b("""-----BEGIN PUBLIC KEY-----
310MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
311gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
31290qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
313ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
314XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
3158Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
316ywIDAQAB
317-----END PUBLIC KEY-----
318""")
319
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400320# Some PKCS#7 stuff. Generated with the openssl command line:
321#
322# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
323#
324# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400325pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400326-----BEGIN PKCS7-----
327MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
328BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
329A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
330MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
331cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
332A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
333HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
334SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
335zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
336LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
337A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
33865w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
339Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
340Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
341bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
342VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
343/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
344Ho4EzbYCOaEAMQA=
345-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400346""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400347
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700348pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700349MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
350BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
351A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
352MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
353cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
354A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
355HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
356SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
357zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
358LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
359A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
36065w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
361Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
362Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
363bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
364VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
365/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
366Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700367""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700368
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400369crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500370-----BEGIN X509 CRL-----
371MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
372SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
373D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
374MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
375MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3764dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3770yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
378vrzEeLDRiiPl92dyyWmu
379-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400380""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400381
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400382crlDataUnsupportedExtension = b("""\
383-----BEGIN X509 CRL-----
384MIIGRzCCBS8CAQIwDQYJKoZIhvcNAQELBQAwJzELMAkGA1UEBhMCVVMxGDAWBgNV
385BAMMD2NyeXB0b2dyYXBoeS5pbxgPMjAxNTAxMDEwMDAwMDBaGA8yMDE2MDEwMTAw
386MDAwMFowggTOMBQCAQAYDzIwMTUwMTAxMDAwMDAwWjByAgEBGA8yMDE1MDEwMTAw
387MDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAn
388MQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQD
389CgEAMHICAQIYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAw
390MDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlw
391dG9ncmFwaHkuaW8wCgYDVR0VBAMKAQEwcgIBAxgPMjAxNTAxMDEwMDAwMDBaMFww
392GAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTArpCkwJzELMAkGA1UE
393BhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNVHRUEAwoBAjByAgEE
394GA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQG
395A1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5
396LmlvMAoGA1UdFQQDCgEDMHICAQUYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQR
397GA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgw
398FgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQQwcgIBBhgPMjAxNTAx
399MDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTAr
400pCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNV
401HRUEAwoBBTByAgEHGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAx
402MDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwP
403Y3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEGMHICAQgYDzIwMTUwMTAxMDAwMDAw
404WjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJ
405BgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQgw
406cgIBCRgPMjAxNTAxMDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAw
407WjA0BgNVHR0ELTArpCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dy
408YXBoeS5pbzAKBgNVHRUEAwoBCTByAgEKGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNV
409HRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJV
410UzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEKMC4CAQsYDzIw
411MTUwMTAxMDAwMDAwWjAYMAoGA1UdFQQDCgEBMAoGAyoDBAQDCgEAMA0GCSqGSIb3
412DQEBCwUAA4IBAQBTaloHlPaCZzYee8LxkWej5meiqxQVNWFoVdjesroa+f1FRrH+
413drRU60Nq97KCKf7f9GNN/J3ZIlQmYhmuDqh12f+XLpotoj1ZRfBz2hjFCkJlv+2c
414oWWGNHgA70ndFoVtcmX088SYpX8E3ARATivS4q2h9WlwV6rO93mhg3HGIe3JpcK4
4157BcW6Poi/ut/zsDOkVbI00SqaujRpdmdCTht82MH3ztjyDkI9KYaD/YEweKSrWOz
416SdEILd164bfBeLuplVI+xpmTEMVNpXBlSXl7+xIw9Vk7p7Q1Pa3k/SvhOldYCm6y
417C1xAg/AAq6w78yzYt18j5Mj0s6eeHi1YpHKw
418-----END X509 CRL-----
419""")
420
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400421
422# A broken RSA private key which can be used to test the error path through
423# PKey.check.
424inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
425MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
4265kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
427OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
428zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
429nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
430HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
431oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
432-----END RSA PRIVATE KEY-----
433""")
434
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400435# certificate with NULL bytes in subjectAltName and common name
436
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400437nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400438MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
439DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
440eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
441RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
442ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
443NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
444DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
445ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
446ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
447hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
448BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
449pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
450vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
451KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
452oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
45308LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
454HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
455BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
456Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
457bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
458AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
459i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
460HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
461kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
462VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
463RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
464-----END CERTIFICATE-----""")
465
Colleen Murphye09399b2016-03-01 17:40:49 -0800466large_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
467MIIJYgIBAAKCAg4AtRua8eIeevRfsj+fkcHr1vmse7Kgb+oX1ssJAvCb1R7JQMnH
468hNDjDP6b3vEkZuPUzlDHymP+cNkXvvi4wJ4miVbO3+SeU4Sh+jmsHeHzGIXat9xW
4699PFtuPM5FQq8zvkY8aDeRYmYwN9JKu4/neMBCBqostYlTEWg+bSytO/qWnyHTHKh
470g0GfaDdqUQPsGQw+J0MgaYIjQOCVASHAPlzbDQLCtuOb587rwTLkZA2GwoHB/LyJ
471BwT0HHgBaiObE12Vs6wi2en0Uu11CiwEuK1KIBcZ2XbE6eApaZa6VH9ysEmUxPt7
472TqyZ4E2oMIYaLPNRxuvozdwTlj1svI1k1FrkaXGc5MTjbgigPMKjIb0T7b/4GNzt
473DhP1LvAeUMnrEi3hJJrcJPXHPqS8/RiytR9xQQW6Sdh4LaA3f9MQm3WSevWage3G
474P8YcCLssOVKsArDjuA52NF5LmYuAeUzXprm4ITDi2oO+0iFBpFW6VPEK4A9vO0Yk
475M/6Wt6tG8zyWhaSH1zFUTwfQ9Yvjyt5w1lrUaAJuoTpwbMVZaDJaEhjOaXU0dyPQ
476jOsePDOQcU6dkeTWsQ3LsHPEEug/X6819TLG5mb3V7bvV9nPFBfTJSCEG794kr90
477XgZfIN71FrdByxLerlbuJI21pPs/nZi9SXi9jAWeiS45/azUxMsyYgJArui+gjq7
478sV1pWiBm6/orAgMBAAECggINQp5L6Yu+oIXBqcSjgq8tfF9M5hd30pLuf/EheHZf
479LA7uAqn2fVGFI2OInIJhXIOT5OxsAXO0xXfltzawZxIFpOFMqajj4F7aYjvSpw9V
480J4EdSiJ/zgv8y1qUdbwEZbHVThRZjoSlrtSzilonBoHZAE0mHtqMz7iRFSk1zz6t
481GunRrvo/lROPentf3TsvHquVNUYI5yaapyO1S7xJhecMIIYSb8nbsHI54FBDGNas
4826mFmpPwI/47/6HTwOEWupnn3NicsjrHzUInOUpaMig4cRR+aP5bjqg/ty8xI8AoN
483evEmCytiWTc+Rvbp1ieN+1jpjN18PjUk80/W7qioHUDt4ieLic8uxWH2VD9SCEnX
484Mpi9tA/FqoZ+2A/3m1OfrY6jiZVE2g+asi9lCK7QVWL39eK82H4rPvtp0/dyo1/i
485ZZz68TXg+m8IgEZcp88hngbkuoTTzpGE73QuPKhGA1uMIimDdqPPB5WP76q+03Oi
486IRR5DfZnqPERed49by0enJ7tKa/gFPZizOV8ALKr0Dp+vfAkxGDLPLBLd2A3//tw
487xg0Q/wltihHSBujv4nYlDXdc5oYyMYZ+Lhc/VuOghHfBq3tgEQ1ECM/ofqXEIdy7
488nVcpZn3Eeq8Jl5CrqxE1ee3NxlzsJHn99yGQpr7mOhW/psJF3XNz80Meg3L4m1T8
489sMBK0GbaassuJhdzb5whAoIBBw48sx1b1WR4XxQc5O/HjHva+l16i2pjUnOUTcDF
490RWmSbIhBm2QQ2rVhO8+fak0tkl6ZnMWW4i0U/X5LOEBbC7+IS8bO3j3Revi+Vw5x
491j96LMlIe9XEub5i/saEWgiz7maCvfzLFU08e1OpT4qPDpP293V400ubA6R7WQTCv
492pBkskGwHeu0l/TuKkVqBFFUTu7KEbps8Gjg7MkJaFriAOv1zis/umK8pVS3ZAM6e
4938w5jfpRccn8Xzta2fRwTB5kCmfxdDsY0oYGxPLRAbW72bORoLGuyyPp/ojeGwoik
494JX9RttErc6FjyZtks370Pa8UL5QskyhMbDhrZW2jFD+RXYM1BrvmZRjbAoIBBwy4
495iFJpuDfytJfz1MWtaL5DqEL/kmiZYAXl6hifNhGu5GAipVIIGsDqEYW4i+VC15aa
4967kOCwz/I5zsB3vSDW96IRs4wXtqEZSibc2W/bqfVi+xcvPPl1ZhQ2EAwa4D/x035
497kyf20ffWOU+1yf2cnijzqs3IzlveUm+meLw5s3Rc+iG7DPWWeCoe1hVwANI1euNc
498pqKwKY905yFyjOje2OgiEU2kS4YME4zGeBys8yo7E42hNnN2EPK6xkkUqzdudLLQ
4998OUlKRTc8AbIf3XG1rpA4VUpTv3hhxGGwCRy6If8zgZQsNYchgNztRGk72Gcb8Dm
500vFSEN3ZtwxU64G3YZzntdcr2WPzxAoIBBw30g6Fgdb/gmVnOpL0//T0ePNDKIMPs
501jVJLaRduhoZgB1Bb9qPUPX0SzRzLZtg1tkZSDjBDoHmOHJfhxUaXt+FLCPPbrE4t
502+nq9n/nBaMM779w9ClqhqLOyGrwKoxjSmhi+TVEHyIxCbXMvPHVHfX9WzxjbcGrN
503ZvRaEVZWo+QlIX8yqdSwqxLk1WtAIRzvlcj7NKum8xBxPed6BNFep/PtgIAmoLT5
504L8wb7EWb2iUdc2KbZ4OaY51lDScqpATgXu3WjXfM+Q52G0mX6Wyd0cjlL711Zrjb
505yLbiueZT94lgIHHRRKtKc8CEqcjkQV5OzABS3P/gQSfgZXBdLKjOpTnKDUq7IBeH
506AoIBBweAOEIAPLQg1QRUrr3xRrYKRwlakgZDii9wJt1l5AgBTICzbTA1vzDJ1JM5
507AqSpCV6w9JWyYVcXK+HLdKBRZLaPPNEQDJ5lOxD6uMziWGl2rg8tj+1xNMWfxiPz
508aTCjoe4EoBUMoTq2gwzRcM2usEQNikXVhnj9Wzaivsaeb4bJ3GRPW5DkrO6JSEtT
509w+gvyMqQM2Hy5k7E7BT46sXVwaj/jZxuqGnebRixXtnp0WixdRIqYWUr1UqLf6hQ
510G7WP2BgoxCMaCmNW8+HMD/xuxucEotoIhZ+GgJKBFoNnjl3BX+qxYdSe9RbL/5Tr
5114It6Jxtj8uETJXEbv9Cg6v1agWPS9YY8RLTBAoIBBwrU2AsAUts6h1LgGLKK3UWZ
512oLH5E+4o+7HqSGRcRodVeN9NBXIYdHHOLeEG6YNGJiJ3bFP5ZQEu9iDsyoFVKJ9O
513Mw/y6dKZuxOCZ+X8FopSROg3yWfdOpAm6cnQZp3WqLNX4n/Q6WvKojfyEiPphjwT
5140ymrUJELXLWJmjUyPoAk6HgC0Gs28ZnEXbyhx7CSbZNFyCU/PNUDZwto3GisIPD3
515le7YjqHugezmjMGlA0sDw5aCXjfbl74vowRFYMO6e3ItApfSRgNV86CDoX74WI/5
516AYU/QVM4wGt8XGT2KwDFJaxYGKsGDMWmXY04dS+WPuetCbouWUusyFwRb9SzFave
517vYeU7Ab/
518-----END RSA PRIVATE KEY-----""")
519
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400520
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400521class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400522 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900523 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400524 """
525
526 def setUp(self):
527 """
528 Create a new private key and start a certificate request (for a test
529 method to finish in one way or another).
530 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800531 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400532 # Basic setup stuff to generate a certificate
533 self.pkey = PKey()
534 self.pkey.generate_key(TYPE_RSA, 384)
535 self.req = X509Req()
536 self.req.set_pubkey(self.pkey)
537 # Authority good you have.
538 self.req.get_subject().commonName = "Yoda root CA"
539 self.x509 = X509()
540 self.subject = self.x509.get_subject()
541 self.subject.commonName = self.req.get_subject().commonName
542 self.x509.set_issuer(self.subject)
543 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400544 now = datetime.now()
545 expire = datetime.now() + timedelta(days=100)
546 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
547 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400548
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800549 def tearDown(self):
550 """
551 Forget all of the pyOpenSSL objects so they can be garbage collected,
552 their memory released, and not interfere with the leak detection code.
553 """
554 self.pkey = self.req = self.x509 = self.subject = None
555 super(X509ExtTests, self).tearDown()
556
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400557 def test_str(self):
558 """
Alex Gaynor31287502015-09-05 16:11:27 -0400559 The string representation of :py:class:`X509Extension` instances as
560 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400561 """
562 # This isn't necessarily the best string representation. Perhaps it
563 # will be changed/improved in the future.
564 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400565 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400566 'CA:FALSE')
567
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400568 def test_type(self):
569 """
Alex Gaynor31287502015-09-05 16:11:27 -0400570 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
571 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400572 """
573 self.assertIdentical(X509Extension, X509ExtensionType)
574 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400575 X509Extension,
576 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400577
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500578 def test_construction(self):
579 """
Alex Gaynor31287502015-09-05 16:11:27 -0400580 :py:class:`X509Extension` accepts an extension type name, a critical
581 flag, and an extension value and returns an
582 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500583 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400584 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500585 self.assertTrue(
586 isinstance(basic, X509ExtensionType),
587 "%r is of type %r, should be %r" % (
588 basic, type(basic), X509ExtensionType))
589
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400590 comment = X509Extension(
591 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500592 self.assertTrue(
593 isinstance(comment, X509ExtensionType),
594 "%r is of type %r, should be %r" % (
595 comment, type(comment), X509ExtensionType))
596
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500597 def test_invalid_extension(self):
598 """
Alex Gaynor31287502015-09-05 16:11:27 -0400599 :py:class:`X509Extension` raises something if it is passed a bad
600 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500601 """
602 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400603 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500604 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400605 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500606
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500607 # Exercise a weird one (an extension which uses the r2i method). This
608 # exercises the codepath that requires a non-NULL ctx to be passed to
609 # X509V3_EXT_nconf. It can't work now because we provide no
610 # configuration database. It might be made to work in the future.
611 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400612 Error, X509Extension, b('proxyCertInfo'), True,
613 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500614
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500615 def test_get_critical(self):
616 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900617 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500618 extension's critical flag.
619 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400620 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500621 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400622 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500623 self.assertFalse(ext.get_critical())
624
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500625 def test_get_short_name(self):
626 """
Alex Gaynor31287502015-09-05 16:11:27 -0400627 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
628 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500629 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400630 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
631 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
632 ext = X509Extension(b('nsComment'), True, b('foo bar'))
633 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500634
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400635 def test_get_data(self):
636 """
Alex Gaynor31287502015-09-05 16:11:27 -0400637 :py:meth:`X509Extension.get_data` returns a string giving the data of
638 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400639 """
640 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
641 # Expect to get back the DER encoded form of CA:true.
642 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
643
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400644 def test_get_data_wrong_args(self):
645 """
Alex Gaynor31287502015-09-05 16:11:27 -0400646 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
647 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400648 """
649 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
650 self.assertRaises(TypeError, ext.get_data, None)
651 self.assertRaises(TypeError, ext.get_data, "foo")
652 self.assertRaises(TypeError, ext.get_data, 7)
653
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400654 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500655 """
Alex Gaynor31287502015-09-05 16:11:27 -0400656 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
657 provided for an extension which does not use it and is ignored in this
658 case.
Rick Dean47262da2009-07-08 16:17:17 -0500659 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400660 ext1 = X509Extension(
661 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400662 self.x509.add_extensions([ext1])
663 self.x509.sign(self.pkey, 'sha1')
664 # This is a little lame. Can we think of a better way?
665 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400666 self.assertTrue(b('X509v3 Basic Constraints:') in text)
667 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400668
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400669 def test_subject(self):
670 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900671 If an extension requires a subject, the :py:data:`subject` parameter to
672 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400673 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400674 ext3 = X509Extension(
675 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400676 self.x509.add_extensions([ext3])
677 self.x509.sign(self.pkey, 'sha1')
678 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400679 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400680
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400681 def test_missing_subject(self):
682 """
Alex Gaynor31287502015-09-05 16:11:27 -0400683 If an extension requires a subject and the :py:data:`subject` parameter
684 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400685 """
686 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400687 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400688
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400689 def test_invalid_subject(self):
690 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900691 If the :py:data:`subject` parameter is given a value which is not an
692 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400693 """
694 for badObj in [True, object(), "hello", [], self]:
695 self.assertRaises(
696 TypeError,
697 X509Extension,
698 'basicConstraints', False, 'CA:TRUE', subject=badObj)
699
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400700 def test_unused_issuer(self):
701 """
Alex Gaynor31287502015-09-05 16:11:27 -0400702 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
703 provided for an extension which does not use it and is ignored in this
704 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400705 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400706 ext1 = X509Extension(
707 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400708 self.x509.add_extensions([ext1])
709 self.x509.sign(self.pkey, 'sha1')
710 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400711 self.assertTrue(b('X509v3 Basic Constraints:') in text)
712 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400713
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400714 def test_issuer(self):
715 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800716 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900717 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400718 """
719 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400720 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400721 issuer=self.x509)
722 self.x509.add_extensions([ext2])
723 self.x509.sign(self.pkey, 'sha1')
724 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400725 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
726 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400727
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400728 def test_missing_issuer(self):
729 """
Alex Gaynor31287502015-09-05 16:11:27 -0400730 If an extension requires an issue and the :py:data:`issuer` parameter
731 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400732 """
733 self.assertRaises(
734 Error,
735 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400736 b('authorityKeyIdentifier'), False,
737 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400738
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400739 def test_invalid_issuer(self):
740 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900741 If the :py:data:`issuer` parameter is given a value which is not an
742 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400743 """
744 for badObj in [True, object(), "hello", [], self]:
745 self.assertRaises(
746 TypeError,
747 X509Extension,
748 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
749 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500750
751
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400752class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500753 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900754 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500755 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400756
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400757 def test_type(self):
758 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900759 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
760 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400761 """
762 self.assertIdentical(PKey, PKeyType)
763 self.assertConsistentType(PKey, 'PKey')
764
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500765 def test_construction(self):
766 """
Alex Gaynor31287502015-09-05 16:11:27 -0400767 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
768 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500769 """
770 self.assertRaises(TypeError, PKey, None)
771 key = PKey()
772 self.assertTrue(
773 isinstance(key, PKeyType),
774 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
775
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500776 def test_pregeneration(self):
777 """
Alex Gaynor31287502015-09-05 16:11:27 -0400778 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
779 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
780 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500781 """
782 key = PKey()
783 self.assertEqual(key.type(), 0)
784 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400785 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500786
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500787 def test_failedGeneration(self):
788 """
Alex Gaynor31287502015-09-05 16:11:27 -0400789 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
790 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
791 the second giving the number of bits to generate. If an invalid type
792 is specified or generation fails, :py:exc:`Error` is raised. If an
793 invalid number of bits is specified, :py:exc:`ValueError` or
794 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500795 """
796 key = PKey()
797 self.assertRaises(TypeError, key.generate_key)
798 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
799 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
800 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500801
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500802 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
803 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500804
Alex Gaynor5bb2bd12016-07-03 10:48:32 -0400805 with pytest.raises(TypeError):
806 key.generate_key(TYPE_RSA, object())
807
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500808 # XXX RSA generation for small values of bits is fairly buggy in a wide
809 # range of OpenSSL versions. I need to figure out what the safe lower
810 # bound for a reasonable number of OpenSSL versions is and explicitly
811 # check for that in the wrapper. The failure behavior is typically an
812 # infinite loop inside OpenSSL.
813
814 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500815
816 # XXX DSA generation seems happy with any number of bits. The DSS
817 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
818 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500819 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500820 # So, it doesn't seem possible to make generate_key fail for
821 # TYPE_DSA with a bits argument which is at least an int.
822
823 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
824
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500825 def test_rsaGeneration(self):
826 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900827 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
828 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500829 """
830 bits = 128
831 key = PKey()
832 key.generate_key(TYPE_RSA, bits)
833 self.assertEqual(key.type(), TYPE_RSA)
834 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400835 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500836
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500837 def test_dsaGeneration(self):
838 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900839 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
840 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500841 """
842 # 512 is a magic number. The DSS (Digital Signature Standard)
843 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
844 # will silently promote any value below 512 to 512.
845 bits = 512
846 key = PKey()
847 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800848 # self.assertEqual(key.type(), TYPE_DSA)
849 # self.assertEqual(key.bits(), bits)
850 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500851
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500852 def test_regeneration(self):
853 """
Alex Gaynor31287502015-09-05 16:11:27 -0400854 :py:meth:`PKeyType.generate_key` can be called multiple times on the
855 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500856 """
857 key = PKey()
858 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400859 key.generate_key(type, bits)
860 self.assertEqual(key.type(), type)
861 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500862
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400863 def test_inconsistentKey(self):
864 """
Alex Gaynor31287502015-09-05 16:11:27 -0400865 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
866 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400867 """
868 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400869 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400870
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400871 def test_check_wrong_args(self):
872 """
Alex Gaynor31287502015-09-05 16:11:27 -0400873 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
874 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400875 """
876 self.assertRaises(TypeError, PKey().check, None)
877 self.assertRaises(TypeError, PKey().check, object())
878 self.assertRaises(TypeError, PKey().check, 1)
879
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400880 def test_check_public_key(self):
881 """
882 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
883 part of the key is available.
884 """
885 # A trick to get a public-only key
886 key = PKey()
887 key.generate_key(TYPE_RSA, 512)
888 cert = X509()
889 cert.set_pubkey(key)
890 pub = cert.get_pubkey()
891 self.assertRaises(TypeError, pub.check)
892
893
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400894class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500895 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900896 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500897 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400898
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500899 def _x509name(self, **attrs):
900 # XXX There's no other way to get a new X509Name yet.
901 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400902 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400903
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500904 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400905 def key(attr):
906 return attr[1]
907 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500908 for k, v in attrs:
909 setattr(name, k, v)
910 return name
911
Rick Deane15b1472009-07-09 15:53:42 -0500912 def test_type(self):
913 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900914 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500915 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400916 self.assertIdentical(X509Name, X509NameType)
917 self.assertEqual(X509NameType.__name__, 'X509Name')
918 self.assertTrue(isinstance(X509NameType, type))
919
Rick Deane15b1472009-07-09 15:53:42 -0500920 name = self._x509name()
921 self.assertTrue(
922 isinstance(name, X509NameType),
923 "%r is of type %r, should be %r" % (
924 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500925
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400926 def test_onlyStringAttributes(self):
927 """
Alex Gaynor31287502015-09-05 16:11:27 -0400928 Attempting to set a non-:py:data:`str` attribute name on an
929 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
930 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400931 """
932 name = self._x509name()
933 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400934 # rejected. Sorry, you're wrong. unicode is automatically converted
935 # to str outside of the control of X509Name, so there's no way to
936 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800937
Alex Gaynor31287502015-09-05 16:11:27 -0400938 # Also, this used to test str subclasses, but that test is less
939 # relevant now that the implementation is in Python instead of C. Also
940 # PyPy automatically converts str subclasses to str when they are
941 # passed to setattr, so we can't test it on PyPy. Apparently CPython
942 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400943 self.assertRaises(TypeError, setattr, name, None, "hello")
944 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400945
946 def test_setInvalidAttribute(self):
947 """
Alex Gaynor31287502015-09-05 16:11:27 -0400948 Attempting to set any attribute name on an :py:class:`X509NameType`
949 instance for which no corresponding NID is defined causes
950 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400951 """
952 name = self._x509name()
953 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
954
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500955 def test_attributes(self):
956 """
Alex Gaynor31287502015-09-05 16:11:27 -0400957 :py:class:`X509NameType` instances have attributes for each standard
958 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500959 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500960 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500961 name.commonName = "foo"
962 self.assertEqual(name.commonName, "foo")
963 self.assertEqual(name.CN, "foo")
964 name.CN = "baz"
965 self.assertEqual(name.commonName, "baz")
966 self.assertEqual(name.CN, "baz")
967 name.commonName = "bar"
968 self.assertEqual(name.commonName, "bar")
969 self.assertEqual(name.CN, "bar")
970 name.CN = "quux"
971 self.assertEqual(name.commonName, "quux")
972 self.assertEqual(name.CN, "quux")
973
Alex Gaynor7778e792016-07-03 23:38:48 -0400974 with pytest.raises(AttributeError):
975 name.foobar
976
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500977 def test_copy(self):
978 """
Alex Gaynor31287502015-09-05 16:11:27 -0400979 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
980 with all the same attributes as an existing :py:class:`X509NameType`
981 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500982 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500983 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500984
985 copy = X509Name(name)
986 self.assertEqual(copy.commonName, "foo")
987 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500988
989 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500990 copy.commonName = "baz"
991 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500992
993 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500994 name.emailAddress = "quux@example.com"
995 self.assertEqual(copy.emailAddress, "bar@example.com")
996
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500997 def test_repr(self):
998 """
Alex Gaynor31287502015-09-05 16:11:27 -0400999 :py:func:`repr` passed an :py:class:`X509NameType` instance should
1000 return a string containing a description of the type and the NIDs which
1001 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001002 """
1003 name = self._x509name(commonName="foo", emailAddress="bar")
1004 self.assertEqual(
1005 repr(name),
1006 "<X509Name object '/emailAddress=bar/CN=foo'>")
1007
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001008 def test_comparison(self):
1009 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001010 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001011 """
1012 def _equality(a, b, assertTrue, assertFalse):
1013 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
1014 assertFalse(a != b)
1015 assertTrue(b == a)
1016 assertFalse(b != a)
1017
1018 def assertEqual(a, b):
1019 _equality(a, b, self.assertTrue, self.assertFalse)
1020
1021 # Instances compare equal to themselves.
1022 name = self._x509name()
1023 assertEqual(name, name)
1024
1025 # Empty instances should compare equal to each other.
1026 assertEqual(self._x509name(), self._x509name())
1027
1028 # Instances with equal NIDs should compare equal to each other.
1029 assertEqual(self._x509name(commonName="foo"),
1030 self._x509name(commonName="foo"))
1031
1032 # Instance with equal NIDs set using different aliases should compare
1033 # equal to each other.
1034 assertEqual(self._x509name(commonName="foo"),
1035 self._x509name(CN="foo"))
1036
1037 # Instances with more than one NID with the same values should compare
1038 # equal to each other.
1039 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
1040 self._x509name(commonName="foo", OU="bar"))
1041
1042 def assertNotEqual(a, b):
1043 _equality(a, b, self.assertFalse, self.assertTrue)
1044
1045 # Instances with different values for the same NID should not compare
1046 # equal to each other.
1047 assertNotEqual(self._x509name(CN="foo"),
1048 self._x509name(CN="bar"))
1049
1050 # Instances with different NIDs should not compare equal to each other.
1051 assertNotEqual(self._x509name(CN="foo"),
1052 self._x509name(OU="foo"))
1053
Alex Gaynor7778e792016-07-03 23:38:48 -04001054 assertNotEqual(self._x509name(), object())
1055
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001056 def _inequality(a, b, assertTrue, assertFalse):
1057 assertTrue(a < b)
1058 assertTrue(a <= b)
1059 assertTrue(b > a)
1060 assertTrue(b >= a)
1061 assertFalse(a > b)
1062 assertFalse(a >= b)
1063 assertFalse(b < a)
1064 assertFalse(b <= a)
1065
1066 def assertLessThan(a, b):
1067 _inequality(a, b, self.assertTrue, self.assertFalse)
1068
1069 # An X509Name with a NID with a value which sorts less than the value
1070 # of the same NID on another X509Name compares less than the other
1071 # X509Name.
1072 assertLessThan(self._x509name(CN="abc"),
1073 self._x509name(CN="def"))
1074
1075 def assertGreaterThan(a, b):
1076 _inequality(a, b, self.assertFalse, self.assertTrue)
1077
1078 # An X509Name with a NID with a value which sorts greater than the
1079 # value of the same NID on another X509Name compares greater than the
1080 # other X509Name.
1081 assertGreaterThan(self._x509name(CN="def"),
1082 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001083
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001084 def test_hash(self):
1085 """
Alex Gaynor31287502015-09-05 16:11:27 -04001086 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1087 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001088 """
1089 a = self._x509name(CN="foo")
1090 b = self._x509name(CN="foo")
1091 self.assertEqual(a.hash(), b.hash())
1092 a.CN = "bar"
1093 self.assertNotEqual(a.hash(), b.hash())
1094
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001095 def test_der(self):
1096 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001097 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001098 """
1099 a = self._x509name(CN="foo", C="US")
1100 self.assertEqual(
1101 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001102 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001103 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001104
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001105 def test_get_components(self):
1106 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001107 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1108 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001109 giving the NIDs and associated values which make up the name.
1110 """
1111 a = self._x509name()
1112 self.assertEqual(a.get_components(), [])
1113 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001114 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001115 a.organizationalUnitName = "bar"
1116 self.assertEqual(
1117 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001118 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001119
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001120 def test_load_nul_byte_attribute(self):
1121 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001122 An :py:class:`OpenSSL.crypto.X509Name` from an
1123 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001124 NUL byte in the value of one of its attributes.
1125 """
1126 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1127 subject = cert.get_subject()
1128 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001129 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001130
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001131 def test_setAttributeFailure(self):
1132 """
1133 If the value of an attribute cannot be set for some reason then
1134 :py:class:`OpenSSL.crypto.Error` is raised.
1135 """
1136 name = self._x509name()
1137 # This value is too long
1138 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1139
1140
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001141class _PKeyInteractionTestsMixin:
1142 """
1143 Tests which involve another thing and a PKey.
1144 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001145
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001146 def signable(self):
1147 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001148 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1149 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001150 """
1151 raise NotImplementedError()
1152
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001153 def test_signWithUngenerated(self):
1154 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001155 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1156 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001157 """
1158 request = self.signable()
1159 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001160 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001161
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001162 def test_signWithPublicKey(self):
1163 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001164 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1165 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001166 """
1167 request = self.signable()
1168 key = PKey()
1169 key.generate_key(TYPE_RSA, 512)
1170 request.set_pubkey(key)
1171 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001172 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001173
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001174 def test_signWithUnknownDigest(self):
1175 """
Alex Gaynor31287502015-09-05 16:11:27 -04001176 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1177 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001178 """
1179 request = self.signable()
1180 key = PKey()
1181 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001182 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001183
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001184 def test_sign(self):
1185 """
Alex Gaynor31287502015-09-05 16:11:27 -04001186 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1187 valid digest function. :py:meth:`X509Req.verify` can be used to check
1188 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001189 """
1190 request = self.signable()
1191 key = PKey()
1192 key.generate_key(TYPE_RSA, 512)
1193 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001194 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001195 # If the type has a verify method, cover that too.
1196 if getattr(request, 'verify', None) is not None:
1197 pub = request.get_pubkey()
1198 self.assertTrue(request.verify(pub))
1199 # Make another key that won't verify.
1200 key = PKey()
1201 key.generate_key(TYPE_RSA, 512)
1202 self.assertRaises(Error, request.verify, key)
1203
1204
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001205class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001206 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001207 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001208 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001209
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001210 def signable(self):
1211 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001212 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001213 """
1214 return X509Req()
1215
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001216 def test_type(self):
1217 """
Alex Gaynor31287502015-09-05 16:11:27 -04001218 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1219 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001220 """
1221 self.assertIdentical(X509Req, X509ReqType)
1222 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001223
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001224 def test_construction(self):
1225 """
Alex Gaynor31287502015-09-05 16:11:27 -04001226 :py:obj:`X509Req` takes no arguments and returns an
1227 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001228 """
1229 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001230 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001231
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001232 def test_version(self):
1233 """
Alex Gaynor31287502015-09-05 16:11:27 -04001234 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1235 certificate request. :py:obj:`X509ReqType.get_version` returns the
1236 X.509 version of the certificate request. The initial value of the
1237 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001238 """
1239 request = X509Req()
1240 self.assertEqual(request.get_version(), 0)
1241 request.set_version(1)
1242 self.assertEqual(request.get_version(), 1)
1243 request.set_version(3)
1244 self.assertEqual(request.get_version(), 3)
1245
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001246 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001247 """
Alex Gaynor31287502015-09-05 16:11:27 -04001248 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1249 with the wrong number of arguments or with a non-:py:obj:`int`
1250 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1251 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001252 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001253 request = X509Req()
1254 self.assertRaises(TypeError, request.set_version)
1255 self.assertRaises(TypeError, request.set_version, "foo")
1256 self.assertRaises(TypeError, request.set_version, 1, 2)
1257 self.assertRaises(TypeError, request.get_version, None)
1258
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001259 def test_get_subject(self):
1260 """
Alex Gaynor31287502015-09-05 16:11:27 -04001261 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1262 subject of the request and which is valid even after the request object
1263 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001264 """
1265 request = X509Req()
1266 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001267 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001268 subject.commonName = "foo"
1269 self.assertEqual(request.get_subject().commonName, "foo")
1270 del request
1271 subject.commonName = "bar"
1272 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001273
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001274 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001275 """
Alex Gaynor31287502015-09-05 16:11:27 -04001276 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1277 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001278 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001279 request = X509Req()
1280 self.assertRaises(TypeError, request.get_subject, None)
1281
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001282 def test_add_extensions(self):
1283 """
Alex Gaynor31287502015-09-05 16:11:27 -04001284 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1285 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001286 """
1287 request = X509Req()
1288 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001289 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001290 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001291 self.assertEqual(len(exts), 1)
1292 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1293 self.assertEqual(exts[0].get_critical(), 1)
1294 self.assertEqual(exts[0].get_data(), b('0\x00'))
1295
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001296 def test_get_extensions(self):
1297 """
1298 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1299 extensions added to this X509 request.
1300 """
1301 request = X509Req()
1302 exts = request.get_extensions()
1303 self.assertEqual(exts, [])
1304 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001305 X509Extension(b('basicConstraints'), True, b('CA:true')),
1306 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001307 exts = request.get_extensions()
1308 self.assertEqual(len(exts), 2)
1309 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1310 self.assertEqual(exts[0].get_critical(), 1)
1311 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1312 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1313 self.assertEqual(exts[1].get_critical(), 0)
1314 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001315
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001316 def test_add_extensions_wrong_args(self):
1317 """
Alex Gaynor31287502015-09-05 16:11:27 -04001318 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1319 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1320 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1321 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001322 """
1323 request = X509Req()
1324 self.assertRaises(TypeError, request.add_extensions)
1325 self.assertRaises(TypeError, request.add_extensions, object())
1326 self.assertRaises(ValueError, request.add_extensions, [object()])
1327 self.assertRaises(TypeError, request.add_extensions, [], None)
1328
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001329 def test_verify_wrong_args(self):
1330 """
1331 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1332 arguments or more than one argument or if passed anything other than a
1333 :py:obj:`PKey` instance as its single argument.
1334 """
1335 request = X509Req()
1336 self.assertRaises(TypeError, request.verify)
1337 self.assertRaises(TypeError, request.verify, object())
1338 self.assertRaises(TypeError, request.verify, PKey(), object())
1339
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001340 def test_verify_uninitialized_key(self):
1341 """
Alex Gaynor31287502015-09-05 16:11:27 -04001342 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1343 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001344 """
1345 request = X509Req()
1346 pkey = PKey()
1347 self.assertRaises(Error, request.verify, pkey)
1348
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001349 def test_verify_wrong_key(self):
1350 """
Alex Gaynor31287502015-09-05 16:11:27 -04001351 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1352 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1353 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001354 """
1355 request = X509Req()
1356 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001357 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001358 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1359 self.assertRaises(Error, request.verify, another_pkey)
1360
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001361 def test_verify_success(self):
1362 """
1363 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001364 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1365 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001366 """
1367 request = X509Req()
1368 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001369 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001370 self.assertEqual(True, request.verify(pkey))
1371
1372
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001373class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001374 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001375 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001376 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001377 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001378
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001379 extpem = """
1380-----BEGIN CERTIFICATE-----
1381MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1382BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1383eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1384MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1385aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1386hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1387Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1388zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1389hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1390TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
139103HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1392MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1393b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1394MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1395uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1396WpOdIpB8KksUTCzV591Nr1wd
1397-----END CERTIFICATE-----
1398 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001399
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001400 def signable(self):
1401 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001402 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001403 """
1404 return X509()
1405
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001406 def test_type(self):
1407 """
Alex Gaynor31287502015-09-05 16:11:27 -04001408 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1409 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001410 """
1411 self.assertIdentical(X509, X509Type)
1412 self.assertConsistentType(X509, 'X509')
1413
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001414 def test_construction(self):
1415 """
Alex Gaynor31287502015-09-05 16:11:27 -04001416 :py:obj:`X509` takes no arguments and returns an instance of
1417 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001418 """
1419 certificate = X509()
1420 self.assertTrue(
1421 isinstance(certificate, X509Type),
1422 "%r is of type %r, should be %r" % (certificate,
1423 type(certificate),
1424 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001425 self.assertEqual(type(X509Type).__name__, 'type')
1426 self.assertEqual(type(certificate).__name__, 'X509')
1427 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001428 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001429
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001430 def test_get_version_wrong_args(self):
1431 """
Alex Gaynor31287502015-09-05 16:11:27 -04001432 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1433 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001434 """
1435 cert = X509()
1436 self.assertRaises(TypeError, cert.get_version, None)
1437
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001438 def test_set_version_wrong_args(self):
1439 """
Alex Gaynor31287502015-09-05 16:11:27 -04001440 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1441 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001442 """
1443 cert = X509()
1444 self.assertRaises(TypeError, cert.set_version)
1445 self.assertRaises(TypeError, cert.set_version, None)
1446 self.assertRaises(TypeError, cert.set_version, 1, None)
1447
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001448 def test_version(self):
1449 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001450 :py:obj:`X509.set_version` sets the certificate version number.
1451 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001452 """
1453 cert = X509()
1454 cert.set_version(1234)
1455 self.assertEquals(cert.get_version(), 1234)
1456
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001457 def test_get_serial_number_wrong_args(self):
1458 """
Alex Gaynor31287502015-09-05 16:11:27 -04001459 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1460 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001461 """
1462 cert = X509()
1463 self.assertRaises(TypeError, cert.get_serial_number, None)
1464
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001465 def test_serial_number(self):
1466 """
Alex Gaynor31287502015-09-05 16:11:27 -04001467 The serial number of an :py:obj:`X509Type` can be retrieved and
1468 modified with :py:obj:`X509Type.get_serial_number` and
1469 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001470 """
1471 certificate = X509()
1472 self.assertRaises(TypeError, certificate.set_serial_number)
1473 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1474 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1475 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1476 self.assertEqual(certificate.get_serial_number(), 0)
1477 certificate.set_serial_number(1)
1478 self.assertEqual(certificate.get_serial_number(), 1)
1479 certificate.set_serial_number(2 ** 32 + 1)
1480 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1481 certificate.set_serial_number(2 ** 64 + 1)
1482 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001483 certificate.set_serial_number(2 ** 128 + 1)
1484 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1485
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001486 def _setBoundTest(self, which):
1487 """
Alex Gaynor31287502015-09-05 16:11:27 -04001488 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1489 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1490 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001491 """
1492 certificate = X509()
1493 set = getattr(certificate, 'set_not' + which)
1494 get = getattr(certificate, 'get_not' + which)
1495
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001496 # Starts with no value.
1497 self.assertEqual(get(), None)
1498
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001499 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001500 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001501 set(when)
1502 self.assertEqual(get(), when)
1503
1504 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001505 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001506 set(when)
1507 self.assertEqual(get(), when)
1508
1509 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001510 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001511 set(when)
1512 self.assertEqual(get(), when)
1513
1514 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001515 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001516
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001517 # The wrong number of arguments results in a TypeError.
1518 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001519 with pytest.raises(TypeError):
1520 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001521 self.assertRaises(TypeError, get, b("foo bar"))
1522
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001523 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001524
1525 def test_set_notBefore(self):
1526 """
Alex Gaynor31287502015-09-05 16:11:27 -04001527 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1528 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1529 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001530 """
1531 self._setBoundTest("Before")
1532
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001533 def test_set_notAfter(self):
1534 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001535 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001536 GENERALIZEDTIME and sets the end of the certificate's validity period
1537 to it.
1538 """
1539 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001540
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001541 def test_get_notBefore(self):
1542 """
Alex Gaynor31287502015-09-05 16:11:27 -04001543 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1544 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001545 internally.
1546 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001547 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001548 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001549
Rick Dean38a05c82009-07-18 01:41:30 -05001550 def test_get_notAfter(self):
1551 """
Alex Gaynor31287502015-09-05 16:11:27 -04001552 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1553 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001554 internally.
1555 """
1556 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001557 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001558
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001559 def test_gmtime_adj_notBefore_wrong_args(self):
1560 """
Alex Gaynor31287502015-09-05 16:11:27 -04001561 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1562 called with the wrong number of arguments or a non-:py:obj:`int`
1563 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001564 """
1565 cert = X509()
1566 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1567 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1568 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1569
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001570 def test_gmtime_adj_notBefore(self):
1571 """
Alex Gaynor31287502015-09-05 16:11:27 -04001572 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1573 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001574 """
1575 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001576 not_before_min = (
1577 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1578 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001579 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001580 not_before = datetime.strptime(
1581 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1582 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001583 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1584 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001585
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001586 def test_gmtime_adj_notAfter_wrong_args(self):
1587 """
Alex Gaynor31287502015-09-05 16:11:27 -04001588 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1589 called with the wrong number of arguments or a non-:py:obj:`int`
1590 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001591 """
1592 cert = X509()
1593 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1594 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1595 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1596
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001597 def test_gmtime_adj_notAfter(self):
1598 """
Alex Gaynor31287502015-09-05 16:11:27 -04001599 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1600 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001601 """
1602 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001603 not_after_min = (
1604 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1605 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001606 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001607 not_after = datetime.strptime(
1608 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1609 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001610 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1611 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001612
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001613 def test_has_expired_wrong_args(self):
1614 """
Alex Gaynor31287502015-09-05 16:11:27 -04001615 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1616 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001617 """
1618 cert = X509()
1619 self.assertRaises(TypeError, cert.has_expired, None)
1620
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001621 def test_has_expired(self):
1622 """
Alex Gaynor31287502015-09-05 16:11:27 -04001623 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1624 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001625 """
1626 cert = X509()
1627 cert.gmtime_adj_notAfter(-1)
1628 self.assertTrue(cert.has_expired())
1629
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001630 def test_has_not_expired(self):
1631 """
Alex Gaynor31287502015-09-05 16:11:27 -04001632 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1633 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001634 """
1635 cert = X509()
1636 cert.gmtime_adj_notAfter(2)
1637 self.assertFalse(cert.has_expired())
1638
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001639 def test_root_has_not_expired(self):
1640 """
Alex Gaynor31287502015-09-05 16:11:27 -04001641 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1642 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001643 """
1644 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1645 self.assertFalse(cert.has_expired())
1646
Rick Dean38a05c82009-07-18 01:41:30 -05001647 def test_digest(self):
1648 """
Alex Gaynor31287502015-09-05 16:11:27 -04001649 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1650 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001651 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001652 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001653 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001654 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1655 # actually matters to the assertion (ie, another arbitrary, good
1656 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001657 # Digest verified with the command:
1658 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001659 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001660 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001661
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001662 def _extcert(self, pkey, extensions):
1663 cert = X509()
1664 cert.set_pubkey(pkey)
1665 cert.get_subject().commonName = "Unit Tests"
1666 cert.get_issuer().commonName = "Unit Tests"
1667 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1668 cert.set_notBefore(when)
1669 cert.set_notAfter(when)
1670
1671 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001672 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001673 return load_certificate(
1674 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1675
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001676 def test_extension_count(self):
1677 """
Alex Gaynor31287502015-09-05 16:11:27 -04001678 :py:obj:`X509.get_extension_count` returns the number of extensions
1679 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001680 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001681 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001682 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1683 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001684 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001685 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001686
1687 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001688 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001689 self.assertEqual(c.get_extension_count(), 0)
1690
1691 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001692 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001693 self.assertEqual(c.get_extension_count(), 1)
1694
1695 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001696 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001697 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001698
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001699 def test_get_extension(self):
1700 """
Alex Gaynor31287502015-09-05 16:11:27 -04001701 :py:obj:`X509.get_extension` takes an integer and returns an
1702 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001703 """
1704 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001705 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1706 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001707 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001708 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001709
1710 cert = self._extcert(pkey, [ca, key, subjectAltName])
1711
1712 ext = cert.get_extension(0)
1713 self.assertTrue(isinstance(ext, X509Extension))
1714 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001715 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001716
1717 ext = cert.get_extension(1)
1718 self.assertTrue(isinstance(ext, X509Extension))
1719 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001720 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001721
1722 ext = cert.get_extension(2)
1723 self.assertTrue(isinstance(ext, X509Extension))
1724 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001725 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001726
1727 self.assertRaises(IndexError, cert.get_extension, -1)
1728 self.assertRaises(IndexError, cert.get_extension, 4)
1729 self.assertRaises(TypeError, cert.get_extension, "hello")
1730
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001731 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001732 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001733 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001734 bytes and this value is reflected in the string representation of the
1735 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001736 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001737 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001738
1739 ext = cert.get_extension(3)
1740 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001741 self.assertEqual(
1742 b("DNS:altnull.python.org\x00example.com, "
1743 "email:null@python.org\x00user@example.org, "
1744 "URI:http://null.python.org\x00http://example.org, "
1745 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1746 b(str(ext)))
1747
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001748 def test_invalid_digest_algorithm(self):
1749 """
Alex Gaynor31287502015-09-05 16:11:27 -04001750 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1751 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001752 """
1753 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001754 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001755
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001756 def test_get_subject_wrong_args(self):
1757 """
Alex Gaynor31287502015-09-05 16:11:27 -04001758 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1759 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001760 """
1761 cert = X509()
1762 self.assertRaises(TypeError, cert.get_subject, None)
1763
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001764 def test_get_subject(self):
1765 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001766 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001767 """
1768 cert = load_certificate(FILETYPE_PEM, self.pemData)
1769 subj = cert.get_subject()
1770 self.assertTrue(isinstance(subj, X509Name))
1771 self.assertEquals(
1772 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001773 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1774 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001775
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001776 def test_set_subject_wrong_args(self):
1777 """
Alex Gaynor31287502015-09-05 16:11:27 -04001778 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1779 the wrong number of arguments or an argument not of type
1780 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001781 """
1782 cert = X509()
1783 self.assertRaises(TypeError, cert.set_subject)
1784 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001785 with pytest.raises(TypeError):
1786 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001787
1788 def test_set_subject(self):
1789 """
Alex Gaynor31287502015-09-05 16:11:27 -04001790 :py:obj:`X509.set_subject` changes the subject of the certificate to
1791 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001792 """
1793 cert = X509()
1794 name = cert.get_subject()
1795 name.C = 'AU'
1796 name.O = 'Unit Tests'
1797 cert.set_subject(name)
1798 self.assertEquals(
1799 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001800 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001801
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001802 def test_get_issuer_wrong_args(self):
1803 """
Alex Gaynor31287502015-09-05 16:11:27 -04001804 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1805 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001806 """
1807 cert = X509()
1808 self.assertRaises(TypeError, cert.get_issuer, None)
1809
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001810 def test_get_issuer(self):
1811 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001812 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001813 """
1814 cert = load_certificate(FILETYPE_PEM, self.pemData)
1815 subj = cert.get_issuer()
1816 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001817 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001818 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001819 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001820 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1821 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001822
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001823 def test_set_issuer_wrong_args(self):
1824 """
Alex Gaynor31287502015-09-05 16:11:27 -04001825 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1826 the wrong number of arguments or an argument not of type
1827 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001828 """
1829 cert = X509()
1830 self.assertRaises(TypeError, cert.set_issuer)
1831 self.assertRaises(TypeError, cert.set_issuer, None)
1832 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1833
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001834 def test_set_issuer(self):
1835 """
Alex Gaynor31287502015-09-05 16:11:27 -04001836 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1837 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001838 """
1839 cert = X509()
1840 name = cert.get_issuer()
1841 name.C = 'AU'
1842 name.O = 'Unit Tests'
1843 cert.set_issuer(name)
1844 self.assertEquals(
1845 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001846 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001847
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001848 def test_get_pubkey_uninitialized(self):
1849 """
Alex Gaynor31287502015-09-05 16:11:27 -04001850 When called on a certificate with no public key,
1851 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001852 """
1853 cert = X509()
1854 self.assertRaises(Error, cert.get_pubkey)
1855
Alex Gaynor7778e792016-07-03 23:38:48 -04001856 def test_set_pubkey_wrong_type(self):
1857 """
1858 :obj:`X509.set_pubkey` raises :obj:`TypeError` when given an object of
1859 the wrong type.
1860 """
1861 cert = X509()
1862 with pytest.raises(TypeError):
1863 cert.set_pubkey(object())
1864
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001865 def test_subject_name_hash_wrong_args(self):
1866 """
Alex Gaynor31287502015-09-05 16:11:27 -04001867 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1868 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001869 """
1870 cert = X509()
1871 self.assertRaises(TypeError, cert.subject_name_hash, None)
1872
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001873 def test_subject_name_hash(self):
1874 """
Alex Gaynor31287502015-09-05 16:11:27 -04001875 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1876 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001877 """
1878 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001879 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001880 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001881 [3350047874, # OpenSSL 0.9.8, MD5
1882 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001883 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001884
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001885 def test_get_signature_algorithm(self):
1886 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001887 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001888 the algorithm used to sign the certificate.
1889 """
1890 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001891 self.assertEqual(
1892 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001893
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001894 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001895 """
Alex Gaynor31287502015-09-05 16:11:27 -04001896 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1897 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001898 """
1899 # This certificate has been modified to indicate a bogus OID in the
1900 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001901 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001902-----BEGIN CERTIFICATE-----
1903MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1904EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1905cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1906MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1907EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1908CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1909AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1910+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1911hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1912BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1913FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1914dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1915aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1916MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1917jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1918PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1919tgI5
1920-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001921""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001922 cert = load_certificate(FILETYPE_PEM, certPEM)
1923 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001924
1925
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001926class X509StoreTests(TestCase):
1927 """
1928 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1929 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001930
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001931 def test_type(self):
1932 """
1933 :py:obj:`X509StoreType` is a type object.
1934 """
1935 self.assertIdentical(X509Store, X509StoreType)
1936 self.assertConsistentType(X509Store, 'X509Store')
1937
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001938 def test_add_cert_wrong_args(self):
1939 store = X509Store()
1940 self.assertRaises(TypeError, store.add_cert)
1941 self.assertRaises(TypeError, store.add_cert, object())
1942 self.assertRaises(TypeError, store.add_cert, X509(), object())
1943
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001944 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001945 """
1946 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1947 certificate store.
1948 """
1949 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001950 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001951 store.add_cert(cert)
1952
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001953 def test_add_cert_rejects_duplicate(self):
1954 """
Alex Gaynor31287502015-09-05 16:11:27 -04001955 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1956 an attempt is made to add the same certificate to the store more than
1957 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001958 """
1959 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1960 store = X509Store()
1961 store.add_cert(cert)
1962 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001963
1964
Rick Dean623ee362009-07-17 12:22:16 -05001965class PKCS12Tests(TestCase):
1966 """
Alex Gaynor31287502015-09-05 16:11:27 -04001967 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1968 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001969 """
1970 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1971
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001972 def test_type(self):
1973 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001974 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001975 """
1976 self.assertIdentical(PKCS12, PKCS12Type)
1977 self.assertConsistentType(PKCS12, 'PKCS12')
1978
Rick Deanf94096c2009-07-18 14:23:06 -05001979 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001980 """
Alex Gaynor31287502015-09-05 16:11:27 -04001981 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1982 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001983 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001984 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001985 self.assertEqual(None, p12.get_certificate())
1986 self.assertEqual(None, p12.get_privatekey())
1987 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001988 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001989
1990 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001991 """
Alex Gaynor31287502015-09-05 16:11:27 -04001992 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1993 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1994 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1995 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001996 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001997 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001998 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001999 self.assertRaises(TypeError, p12.set_certificate, PKey())
2000 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05002001 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002002 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
2003 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05002004 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
2005 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
2006 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04002007 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05002008 self.assertRaises(TypeError, p12.set_friendlyname, 6)
2009 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05002010
2011 def test_key_only(self):
2012 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002013 A :py:obj:`PKCS12` with only a private key can be exported using
2014 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002015 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002016 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002017 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002018 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002019 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05002020 self.assertEqual(None, p12.get_certificate())
2021 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002022 try:
2023 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2024 except Error:
2025 # Some versions of OpenSSL will throw an exception
2026 # for this nearly useless PKCS12 we tried to generate:
2027 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2028 return
Rick Dean623ee362009-07-17 12:22:16 -05002029 p12 = load_pkcs12(dumped_p12, passwd)
2030 self.assertEqual(None, p12.get_ca_certificates())
2031 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002032
2033 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2034 # future this will be improved.
2035 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05002036
2037 def test_cert_only(self):
2038 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002039 A :py:obj:`PKCS12` with only a certificate can be exported using
2040 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002041 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002042 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002043 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002044 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002045 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05002046 self.assertEqual(cert, p12.get_certificate())
2047 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002048 try:
2049 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2050 except Error:
2051 # Some versions of OpenSSL will throw an exception
2052 # for this nearly useless PKCS12 we tried to generate:
2053 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2054 return
Rick Dean623ee362009-07-17 12:22:16 -05002055 p12 = load_pkcs12(dumped_p12, passwd)
2056 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002057
2058 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
2059 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2060
2061 # Oh ho. It puts the certificate into the ca certificates list, in
2062 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2063 # that to check to see if it reconstructed the certificate we expected
2064 # it to. At some point, hopefully this will change so that
2065 # p12.get_certificate() is actually what returns the loaded
2066 # certificate.
2067 self.assertEqual(
2068 cleartextCertificatePEM,
2069 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002070
Alex Gaynor31287502015-09-05 16:11:27 -04002071 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2072 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002073 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002074 Generate a PKCS12 object with components from PEM. Verify that the set
2075 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002076 """
Rick Deanf94096c2009-07-18 14:23:06 -05002077 p12 = PKCS12()
2078 if cert_pem:
2079 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2080 self.assertEqual(ret, None)
2081 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002082 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002083 self.assertEqual(ret, None)
2084 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002085 ret = p12.set_ca_certificates(
2086 (load_certificate(FILETYPE_PEM, ca_pem),)
2087 )
Rick Deanf94096c2009-07-18 14:23:06 -05002088 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002089 if friendly_name:
2090 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002091 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002092 return p12
2093
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002094 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002095 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002096 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002097 Use openssl program to confirm three components are recoverable from a
2098 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002099 """
2100 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002101 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002102 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2103 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002104 self.assertEqual(recovered_key[-len(key):], key)
2105 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002106 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002107 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2108 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002109 self.assertEqual(recovered_cert[-len(cert):], cert)
2110 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002111 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002112 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2113 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002114 self.assertEqual(recovered_cert[-len(ca):], ca)
2115
Stephen Holsapple38482622014-04-05 20:29:34 -07002116 def verify_pkcs12_container(self, p12):
2117 """
2118 Verify that the PKCS#12 container contains the correct client
2119 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002120
2121 :param p12: The PKCS12 instance to verify.
2122 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002123 """
2124 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2125 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002126 self.assertEqual(
2127 (client_cert_pem, client_key_pem, None),
2128 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002129
Rick Deanf94096c2009-07-18 14:23:06 -05002130 def test_load_pkcs12(self):
2131 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002132 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002133 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002134 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002135 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002136 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002137 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002138 pem,
2139 b"pkcs12",
2140 b"-export",
2141 b"-clcerts",
2142 b"-passout",
2143 b"pass:" + passwd
2144 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002145 p12 = load_pkcs12(p12_str, passphrase=passwd)
2146 self.verify_pkcs12_container(p12)
2147
Abraham Martinc5484ba2015-03-25 15:33:05 +00002148 def test_load_pkcs12_text_passphrase(self):
2149 """
2150 A PKCS12 string generated using the openssl command line can be loaded
2151 with :py:obj:`load_pkcs12` and its components extracted and examined.
2152 Using text as passphrase instead of bytes. DeprecationWarning expected.
2153 """
2154 pem = client_key_pem + client_cert_pem
2155 passwd = b"whatever"
2156 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2157 b"-passout", b"pass:" + passwd)
2158 with catch_warnings(record=True) as w:
2159 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002160 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002161
2162 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002163 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002164 WARNING_TYPE_EXPECTED
2165 ),
2166 str(w[-1].message)
2167 )
2168 self.assertIs(w[-1].category, DeprecationWarning)
2169
Abraham Martinc5484ba2015-03-25 15:33:05 +00002170 self.verify_pkcs12_container(p12)
2171
Stephen Holsapple38482622014-04-05 20:29:34 -07002172 def test_load_pkcs12_no_passphrase(self):
2173 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002174 A PKCS12 string generated using openssl command line can be loaded with
2175 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2176 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002177 """
2178 pem = client_key_pem + client_cert_pem
2179 p12_str = _runopenssl(
2180 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2181 p12 = load_pkcs12(p12_str)
2182 self.verify_pkcs12_container(p12)
2183
Stephen Holsapple38482622014-04-05 20:29:34 -07002184 def _dump_and_load(self, dump_passphrase, load_passphrase):
2185 """
2186 A helper method to dump and load a PKCS12 object.
2187 """
2188 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2189 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2190 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2191
Stephen Holsapple38482622014-04-05 20:29:34 -07002192 def test_load_pkcs12_null_passphrase_load_empty(self):
2193 """
2194 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002195 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002196 extracted and examined.
2197 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002198 self.verify_pkcs12_container(
2199 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002200
Stephen Holsapple38482622014-04-05 20:29:34 -07002201 def test_load_pkcs12_null_passphrase_load_null(self):
2202 """
2203 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002204 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002205 extracted and examined.
2206 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002207 self.verify_pkcs12_container(
2208 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002209
Stephen Holsapple38482622014-04-05 20:29:34 -07002210 def test_load_pkcs12_empty_passphrase_load_empty(self):
2211 """
2212 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002213 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002214 extracted and examined.
2215 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002216 self.verify_pkcs12_container(
2217 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002218
Stephen Holsapple38482622014-04-05 20:29:34 -07002219 def test_load_pkcs12_empty_passphrase_load_null(self):
2220 """
2221 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002222 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002223 extracted and examined.
2224 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002225 self.verify_pkcs12_container(
2226 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002227
Rick Deanee568302009-07-24 09:56:29 -05002228 def test_load_pkcs12_garbage(self):
2229 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002230 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2231 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002232 """
2233 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002234 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002235 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2236 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002237
Rick Deanf94096c2009-07-18 14:23:06 -05002238 def test_replace(self):
2239 """
Alex Gaynor31287502015-09-05 16:11:27 -04002240 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2241 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002242 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002243 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002244 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2245 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2246 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002247 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002248 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002249 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002250 self.assertEqual(1, len(p12.get_ca_certificates()))
2251 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002252 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002253 self.assertEqual(2, len(p12.get_ca_certificates()))
2254 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2255 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2256
Rick Deanf94096c2009-07-18 14:23:06 -05002257 def test_friendly_name(self):
2258 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002259 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002260 :py:obj:`PKCS12.get_friendlyname` and
2261 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2262 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002263 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002264 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002265 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002266 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002267 p12.set_friendlyname(friendly_name)
2268 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002269 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002270 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002271 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002272 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002273 # We would use the openssl program to confirm the friendly
2274 # name, but it is not possible. The pkcs12 command
2275 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002276 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002277 self.check_recovery(
2278 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2279 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002280
Rick Deanf94096c2009-07-18 14:23:06 -05002281 def test_various_empty_passphrases(self):
2282 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002283 Test that missing, None, and '' passphrases are identical for PKCS12
2284 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002285 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002286 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002287 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002288 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2289 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2290 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2291 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2292 self.check_recovery(
2293 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2294 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002295
Rick Deanf94096c2009-07-18 14:23:06 -05002296 def test_removing_ca_cert(self):
2297 """
Alex Gaynor31287502015-09-05 16:11:27 -04002298 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2299 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002300 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002301 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2302 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002303 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002304
Rick Deanf94096c2009-07-18 14:23:06 -05002305 def test_export_without_mac(self):
2306 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002307 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002308 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002309 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002310 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002311 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002312 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002313 self.check_recovery(
2314 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002315 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002316
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002317 def test_load_without_mac(self):
2318 """
2319 Loading a PKCS12 without a MAC does something other than crash.
2320 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002321 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002322 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2323 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002324 try:
2325 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2326 # The person who generated this PCKS12 should be flogged,
2327 # or better yet we should have a means to determine
2328 # whether a PCKS12 had a MAC that was verified.
2329 # Anyway, libopenssl chooses to allow it, so the
2330 # pyopenssl binding does as well.
2331 self.assertTrue(isinstance(recovered_p12, PKCS12))
2332 except Error:
2333 # Failing here with an exception is preferred as some openssl
2334 # versions do.
2335 pass
Rick Dean623ee362009-07-17 12:22:16 -05002336
Rick Dean25bcc1f2009-07-20 11:53:13 -05002337 def test_zero_len_list_for_ca(self):
2338 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002339 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002340 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002341 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002342 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002343 p12.set_ca_certificates([])
2344 self.assertEqual((), p12.get_ca_certificates())
2345 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2346 self.check_recovery(
2347 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2348 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002349
Rick Deanf94096c2009-07-18 14:23:06 -05002350 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002351 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002352 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002353 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002354 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002355 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002356 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002357 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002358
Abraham Martinc5484ba2015-03-25 15:33:05 +00002359 def test_export_without_bytes(self):
2360 """
2361 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2362 """
2363 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2364
2365 with catch_warnings(record=True) as w:
2366 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002367 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002368 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002369 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002370 WARNING_TYPE_EXPECTED
2371 ),
2372 str(w[-1].message)
2373 )
2374 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002375 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002376 dumped_p12,
2377 key=server_key_pem,
2378 cert=server_cert_pem,
2379 passwd=b"randomtext"
2380 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002381
Rick Deanf94096c2009-07-18 14:23:06 -05002382 def test_key_cert_mismatch(self):
2383 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002384 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002385 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002386 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002387 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2388 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002389
2390
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002391# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002392_cmdLineQuoteRe = re.compile(br'(\\*)"')
2393_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002394
2395
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002396def cmdLineQuote(s):
2397 """
2398 Internal method for quoting a single command-line argument.
2399
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002400 See http://www.perlmonks.org/?node_id=764004
2401
Jonathan Ballet648875f2011-07-16 14:14:58 +09002402 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002403 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002404 cmd.exe-style quoting
2405
Jonathan Ballet648875f2011-07-16 14:14:58 +09002406 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002407 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002408 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002409 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2410 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002411
2412
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002413def quoteArguments(arguments):
2414 """
2415 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002416 a similar API. This allows the list passed to
2417 :py:obj:`reactor.spawnProcess` to match the child process's
2418 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002419
Jonathan Ballet648875f2011-07-16 14:14:58 +09002420 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002421 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002422
Jonathan Ballet648875f2011-07-16 14:14:58 +09002423 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002424 :return: A space-delimited string containing quoted versions of
2425 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002426 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002427 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002428
2429
Rick Dean4c9ad612009-07-17 15:05:22 -05002430def _runopenssl(pem, *args):
2431 """
2432 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002433 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002434 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002435 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002436 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002437 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2438 for arg in args
2439 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002440 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002441 command = b"openssl " + quoteArguments(args)
2442 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002443 proc.stdin.write(pem)
2444 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002445 output = proc.stdout.read()
2446 proc.stdout.close()
2447 proc.wait()
2448 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002449
2450
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002451class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002452 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002453 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002454 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002455 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002456 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002457 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002458 """
2459 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002460
2461 assert True is key._only_public
2462 assert 2048 == key.bits()
2463 assert TYPE_RSA == key.type()
2464
2465 def test_invalid_type(self):
2466 """
2467 load_publickey doesn't support FILETYPE_TEXT.
2468 """
2469 with pytest.raises(ValueError):
2470 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2471
2472 def test_invalid_key_format(self):
2473 """
2474 load_publickey explodes on incorrect keys.
2475 """
2476 with pytest.raises(Error):
2477 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2478
2479 def test_tolerates_unicode_strings(self):
2480 """
2481 load_publickey works with text strings, not just bytes.
2482 """
2483 serialized = cleartextPublicKeyPEM.decode('ascii')
2484 key = load_publickey(FILETYPE_PEM, serialized)
2485 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2486
2487 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002488
2489
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002490class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002491 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002492 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002493
2494 Add new tests to `TestFunctions` above.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002495 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002496
2497 def test_load_privatekey_invalid_format(self):
2498 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002499 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2500 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002501 """
2502 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2503
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002504 def test_load_privatekey_invalid_passphrase_type(self):
2505 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002506 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2507 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002508 """
2509 self.assertRaises(
2510 TypeError,
2511 load_privatekey,
2512 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2513
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002514 def test_load_privatekey_wrong_args(self):
2515 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002516 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2517 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002518 """
2519 self.assertRaises(TypeError, load_privatekey)
2520
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002521 def test_load_privatekey_wrongPassphrase(self):
2522 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002523 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2524 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002525 """
2526 self.assertRaises(
2527 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002528 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002529
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002530 def test_load_privatekey_passphraseWrongType(self):
2531 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002532 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2533 a passphrase with a private key encoded in a format, that doesn't
2534 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002535 """
2536 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2537 blob = dump_privatekey(FILETYPE_ASN1, key)
2538 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002539 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002540
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002541 def test_load_privatekey_passphrase(self):
2542 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002543 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2544 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002545 """
2546 key = load_privatekey(
2547 FILETYPE_PEM, encryptedPrivateKeyPEM,
2548 encryptedPrivateKeyPEMPassphrase)
2549 self.assertTrue(isinstance(key, PKeyType))
2550
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002551 def test_load_privatekey_passphrase_exception(self):
2552 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002553 If the passphrase callback raises an exception, that exception is
2554 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002555 """
2556 def cb(ignored):
2557 raise ArithmeticError
2558
Alex Gaynor791212d2015-09-05 15:46:08 -04002559 with pytest.raises(ArithmeticError):
2560 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002561
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002562 def test_load_privatekey_wrongPassphraseCallback(self):
2563 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002564 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2565 is passed an encrypted PEM and a passphrase callback which returns an
2566 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002567 """
2568 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002569
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002570 def cb(*a):
2571 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002572 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002573 self.assertRaises(
2574 Error,
2575 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2576 self.assertTrue(called)
2577
2578 def test_load_privatekey_passphraseCallback(self):
2579 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002580 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2581 encrypted PEM string if given a passphrase callback which returns the
2582 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002583 """
2584 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002585
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002586 def cb(writing):
2587 called.append(writing)
2588 return encryptedPrivateKeyPEMPassphrase
2589 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2590 self.assertTrue(isinstance(key, PKeyType))
2591 self.assertEqual(called, [False])
2592
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002593 def test_load_privatekey_passphrase_wrong_return_type(self):
2594 """
2595 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2596 callback returns something other than a byte string.
2597 """
2598 self.assertRaises(
2599 ValueError,
2600 load_privatekey,
2601 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2602
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002603 def test_dump_privatekey_wrong_args(self):
2604 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002605 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2606 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002607 """
2608 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002609 # If cipher name is given, password is required.
2610 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002611 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002612
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002613 def test_dump_privatekey_unknown_cipher(self):
2614 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002615 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2616 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002617 """
2618 key = PKey()
2619 key.generate_key(TYPE_RSA, 512)
2620 self.assertRaises(
2621 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002622 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002623
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002624 def test_dump_privatekey_invalid_passphrase_type(self):
2625 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002626 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2627 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002628 """
2629 key = PKey()
2630 key.generate_key(TYPE_RSA, 512)
2631 self.assertRaises(
2632 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002633 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002634
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002635 def test_dump_privatekey_invalid_filetype(self):
2636 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002637 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2638 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002639 """
2640 key = PKey()
2641 key.generate_key(TYPE_RSA, 512)
2642 self.assertRaises(ValueError, dump_privatekey, 100, key)
2643
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002644 def test_load_privatekey_passphraseCallbackLength(self):
2645 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002646 :py:obj:`crypto.load_privatekey` should raise an error when the
2647 passphrase provided by the callback is too long, not silently truncate
2648 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002649 """
2650 def cb(ignored):
2651 return "a" * 1025
2652
Alex Gaynor791212d2015-09-05 15:46:08 -04002653 with pytest.raises(ValueError):
2654 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002655
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002656 def test_dump_privatekey_passphrase(self):
2657 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002658 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2659 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002660 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002661 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002662 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002663 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2664 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002665 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2666 self.assertTrue(isinstance(loadedKey, PKeyType))
2667 self.assertEqual(loadedKey.type(), key.type())
2668 self.assertEqual(loadedKey.bits(), key.bits())
2669
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002670 def test_dump_privatekey_passphraseWrongType(self):
2671 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002672 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2673 a passphrase with a private key encoded in a format, that doesn't
2674 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002675 """
2676 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002677 with pytest.raises(ValueError):
2678 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002679
Rick Dean5b7b6372009-04-01 11:34:06 -05002680 def test_dump_certificate(self):
2681 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002682 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002683 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002684 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002685 cert = load_certificate(FILETYPE_PEM, pemData)
2686 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2687 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2688 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002689 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002690 self.assertEqual(dumped_der, good_der)
2691 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2692 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2693 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2694 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002695 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002696 self.assertEqual(dumped_text, good_text)
2697
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002698 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002699 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002700 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002701 """
2702 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002703 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002704 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2705 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002706
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002707 def test_dump_privatekey_asn1(self):
2708 """
2709 :py:obj:`dump_privatekey` writes a DER
2710 """
2711 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2712 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2713
Rick Dean5b7b6372009-04-01 11:34:06 -05002714 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002715 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002716 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002717 self.assertEqual(dumped_der, good_der)
2718 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2719 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2720 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002721
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002722 def test_dump_privatekey_text(self):
2723 """
2724 :py:obj:`dump_privatekey` writes a text
2725 """
2726 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2727 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2728
Rick Dean5b7b6372009-04-01 11:34:06 -05002729 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002730 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002731 self.assertEqual(dumped_text, good_text)
2732
Cory Benfield6492f7c2015-10-27 16:57:58 +09002733 def test_dump_publickey_pem(self):
2734 """
Cory Benfield11c10192015-10-27 17:23:03 +09002735 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002736 """
2737 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2738 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002739 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002740
2741 def test_dump_publickey_asn1(self):
2742 """
Cory Benfield11c10192015-10-27 17:23:03 +09002743 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002744 """
2745 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2746 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2747 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2748 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002749 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002750
Cory Benfielde02c7d82015-10-27 17:34:49 +09002751 def test_dump_publickey_invalid_type(self):
2752 """
2753 dump_publickey doesn't support FILETYPE_TEXT.
2754 """
2755 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2756
2757 with pytest.raises(ValueError):
2758 dump_publickey(FILETYPE_TEXT, key)
2759
Rick Dean5b7b6372009-04-01 11:34:06 -05002760 def test_dump_certificate_request(self):
2761 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002762 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002763 """
Alex Gaynor31287502015-09-05 16:11:27 -04002764 req = load_certificate_request(
2765 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002766 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2767 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2768 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002769 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002770 self.assertEqual(dumped_der, good_der)
2771 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2772 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2773 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2774 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002775 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002776 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002777 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002778
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002779 def test_dump_privatekey_passphraseCallback(self):
2780 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002781 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2782 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002783 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002784 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002785 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002786
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002787 def cb(writing):
2788 called.append(writing)
2789 return passphrase
2790 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002791 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2792 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002793 self.assertEqual(called, [True])
2794 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2795 self.assertTrue(isinstance(loadedKey, PKeyType))
2796 self.assertEqual(loadedKey.type(), key.type())
2797 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002798
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002799 def test_dump_privatekey_passphrase_exception(self):
2800 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002801 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002802 by the passphrase callback.
2803 """
2804 def cb(ignored):
2805 raise ArithmeticError
2806
2807 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002808 with pytest.raises(ArithmeticError):
2809 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002810
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002811 def test_dump_privatekey_passphraseCallbackLength(self):
2812 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002813 :py:obj:`crypto.dump_privatekey` should raise an error when the
2814 passphrase provided by the callback is too long, not silently truncate
2815 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002816 """
2817 def cb(ignored):
2818 return "a" * 1025
2819
2820 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002821 with pytest.raises(ValueError):
2822 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002823
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002824 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002825 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002826 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2827 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002828 """
2829 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2830 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2831
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002832 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002833 """
2834 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2835 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2836 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002837 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2838 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2839
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002840 def test_load_pkcs7_data_invalid(self):
2841 """
2842 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2843 :py:obj:`Error` is raised.
2844 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002845 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002846
Alex Gaynor09a386e2016-07-03 09:32:44 -04002847 def test_load_pkcs7_type_invalid(self):
2848 """
2849 If the type passed to :obj:`load_pkcs7_data`, :obj:`ValueError` is
2850 raised.
2851 """
2852 with pytest.raises(ValueError):
2853 load_pkcs7_data(object(), b"foo")
2854
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002855
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002856class LoadCertificateTests(TestCase):
2857 """
2858 Tests for :py:obj:`load_certificate_request`.
2859 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002860
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002861 def test_badFileType(self):
2862 """
2863 If the file type passed to :py:obj:`load_certificate_request` is
2864 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2865 :py:class:`ValueError` is raised.
2866 """
Alex Gaynor7778e792016-07-03 23:38:48 -04002867 with pytest.raises(ValueError):
2868 load_certificate_request(object(), b"")
2869 with pytest.raises(ValueError):
2870 load_certificate(object(), b"")
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002871
2872
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002873class PKCS7Tests(TestCase):
2874 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002875 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002876 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002877
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002878 def test_type(self):
2879 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002880 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002881 """
2882 self.assertTrue(isinstance(PKCS7Type, type))
2883 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2884
2885 # XXX This doesn't currently work.
2886 # self.assertIdentical(PKCS7, PKCS7Type)
2887
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002888 # XXX Opposite results for all these following methods
2889
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002890 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002891 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002892 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2893 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002894 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002895 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2896 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2897
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002898 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002899 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002900 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2901 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002902 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002903 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2904 self.assertTrue(pkcs7.type_is_signed())
2905
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002906 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002907 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002908 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2909 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002910 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002911 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2912 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2913
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002914 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002915 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002916 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2917 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002918 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002919 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2920 self.assertFalse(pkcs7.type_is_enveloped())
2921
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002922 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002923 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002924 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2925 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002926 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002927 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2928 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2929
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002930 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002931 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002932 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2933 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002934 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002935 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2936 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2937
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002938 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002939 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002940 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2941 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002942 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002943 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2944 self.assertFalse(pkcs7.type_is_data())
2945
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002946 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002947 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002948 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2949 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002950 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002951 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2952 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2953
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002954 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002955 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002956 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2957 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002958 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002959 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2960 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2961
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002962 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002963 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002964 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2965 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002966 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002967 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002968 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002969
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002970 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002971 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002972 If an attribute other than one of the methods tested here is accessed
2973 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2974 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002975 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002976 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2977 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2978
2979
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002980class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002981 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002982 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002983 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002984
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002985 def signable(self):
2986 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002987 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002988 """
2989 return NetscapeSPKI()
2990
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002991 def test_type(self):
2992 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002993 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2994 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002995 """
2996 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2997 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2998
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002999 def test_construction(self):
3000 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003001 :py:obj:`NetscapeSPKI` returns an instance of
3002 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003003 """
3004 nspki = NetscapeSPKI()
3005 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
3006
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003007 def test_invalid_attribute(self):
3008 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003009 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
3010 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003011 """
3012 nspki = NetscapeSPKI()
3013 self.assertRaises(AttributeError, lambda: nspki.foo)
3014
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003015 def test_b64_encode(self):
3016 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003017 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
3018 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003019 """
3020 nspki = NetscapeSPKI()
3021 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003022 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003023
3024
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003025class TestRevoked(object):
3026 """
3027 Please add test cases for the Revoked class here if possible. This class
3028 holds the new py.test style tests.
3029 """
3030 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3031 """
3032 The get_reason method on the Revoked class checks to see if the
3033 extension is NID_crl_reason and should skip it otherwise. This test
3034 loads a CRL with extensions it should ignore.
3035 """
3036 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3037 revoked = crl.get_revoked()
3038 reason = revoked[1].get_reason()
3039 assert reason == b'Unspecified'
3040
3041 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3042 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3043 revoked = crl.get_revoked()
3044 revoked[1].set_reason(None)
3045 reason = revoked[1].get_reason()
3046 assert reason is None
3047
3048
Rick Dean536ba022009-07-24 23:57:27 -05003049class RevokedTests(TestCase):
3050 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003051 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3052 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003053 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003054
Rick Dean536ba022009-07-24 23:57:27 -05003055 def test_construction(self):
3056 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003057 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003058 that it is empty.
3059 """
3060 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003061 self.assertTrue(isinstance(revoked, Revoked))
3062 self.assertEquals(type(revoked), Revoked)
3063 self.assertEquals(revoked.get_serial(), b('00'))
3064 self.assertEquals(revoked.get_rev_date(), None)
3065 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003066
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003067 def test_construction_wrong_args(self):
3068 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003069 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3070 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003071 """
3072 self.assertRaises(TypeError, Revoked, None)
3073 self.assertRaises(TypeError, Revoked, 1)
3074 self.assertRaises(TypeError, Revoked, "foo")
3075
Rick Dean536ba022009-07-24 23:57:27 -05003076 def test_serial(self):
3077 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003078 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003079 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003080 with grace.
3081 """
3082 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003083 ret = revoked.set_serial(b('10b'))
3084 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003085 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003086 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003087
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003088 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003089 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003090 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003091
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003092 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003093 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003094 self.assertRaises(TypeError, revoked.get_serial, 1)
3095 self.assertRaises(TypeError, revoked.get_serial, None)
3096 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003097
Rick Dean536ba022009-07-24 23:57:27 -05003098 def test_date(self):
3099 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003100 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003101 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003102 with grace.
3103 """
3104 revoked = Revoked()
3105 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003106 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003107
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003108 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003109 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003110 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003111 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003112 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003113
Rick Dean6385faf2009-07-26 00:07:47 -05003114 def test_reason(self):
3115 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003116 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003117 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003118 as "set". Likewise, each reason of all_reasons() must work.
3119 """
3120 revoked = Revoked()
3121 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003122 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003123 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003124 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003125 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003126 self.assertEquals(
3127 reason.lower().replace(b(' '), b('')),
3128 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003129 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003130
3131 revoked.set_reason(None)
3132 self.assertEqual(revoked.get_reason(), None)
3133
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003134 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003135 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003136 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003137 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003138 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003139 """
3140 revoked = Revoked()
3141 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003142 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003143
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003144 def test_get_reason_wrong_arguments(self):
3145 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003146 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3147 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003148 """
3149 revoked = Revoked()
3150 self.assertRaises(TypeError, revoked.get_reason, None)
3151 self.assertRaises(TypeError, revoked.get_reason, 1)
3152 self.assertRaises(TypeError, revoked.get_reason, "foo")
3153
3154
Rick Dean536ba022009-07-24 23:57:27 -05003155class CRLTests(TestCase):
3156 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003157 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003158 """
3159 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3160 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3161
Dan Sully44e767a2016-06-04 18:05:27 -07003162 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3163 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3164 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3165 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3166 intermediate_server_cert = load_certificate(
3167 FILETYPE_PEM, intermediate_server_cert_pem)
3168 intermediate_server_key = load_privatekey(
3169 FILETYPE_PEM, intermediate_server_key_pem)
3170
Rick Dean536ba022009-07-24 23:57:27 -05003171 def test_construction(self):
3172 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003173 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003174 that it is empty
3175 """
3176 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003177 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003178 self.assertEqual(crl.get_revoked(), None)
3179
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003180 def test_construction_wrong_args(self):
3181 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003182 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3183 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003184 """
3185 self.assertRaises(TypeError, CRL, 1)
3186 self.assertRaises(TypeError, CRL, "")
3187 self.assertRaises(TypeError, CRL, None)
3188
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003189 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003190 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003191 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003192 """
3193 crl = CRL()
3194 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003195 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003196 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003197 revoked.set_serial(b('3ab'))
3198 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003199 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003200 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003201
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003202 def test_export_pem(self):
3203 """
3204 If not passed a format, ``CRL.export`` returns a "PEM" format string
3205 representing a serial number, a revoked reason, and certificate issuer
3206 information.
3207 """
3208 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003209 # PEM format
3210 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003211 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003212
3213 # These magic values are based on the way the CRL above was constructed
3214 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003215 text.index(b('Serial Number: 03AB'))
3216 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003217 text.index(
3218 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3219 )
3220
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003221 def test_export_der(self):
3222 """
3223 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3224 "DER" format string representing a serial number, a revoked reason, and
3225 certificate issuer information.
3226 """
3227 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003228
3229 # DER format
3230 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003231 text = _runopenssl(
3232 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3233 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003234 text.index(b('Serial Number: 03AB'))
3235 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003236 text.index(
3237 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3238 )
3239
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003240 def test_export_text(self):
3241 """
3242 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3243 text format string like the one produced by the openssl command line
3244 tool.
3245 """
3246 crl = self._get_crl()
3247
3248 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3249 text = _runopenssl(
3250 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3251 )
Rick Dean536ba022009-07-24 23:57:27 -05003252
3253 # text format
3254 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3255 self.assertEqual(text, dumped_text)
3256
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003257 def test_export_custom_digest(self):
3258 """
3259 If passed the name of a digest function, ``CRL.export`` uses a
3260 signature algorithm based on that digest function.
3261 """
3262 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003263 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003264 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3265 text.index(b('Signature Algorithm: sha1'))
3266
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003267 def test_export_md5_digest(self):
3268 """
3269 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3270 not emit a deprecation warning.
3271 """
3272 crl = self._get_crl()
3273 with catch_warnings(record=True) as catcher:
3274 simplefilter("always")
3275 self.assertEqual(0, len(catcher))
3276 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3277 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3278 text.index(b('Signature Algorithm: md5'))
3279
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003280 def test_export_default_digest(self):
3281 """
3282 If not passed the name of a digest function, ``CRL.export`` uses a
3283 signature algorithm based on MD5 and emits a deprecation warning.
3284 """
3285 crl = self._get_crl()
3286 with catch_warnings(record=True) as catcher:
3287 simplefilter("always")
3288 dumped_crl = crl.export(self.cert, self.pkey)
3289 self.assertEqual(
3290 "The default message digest (md5) is deprecated. "
3291 "Pass the name of a message digest explicitly.",
3292 str(catcher[0].message),
3293 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003294 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3295 text.index(b('Signature Algorithm: md5'))
3296
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003297 def test_export_invalid(self):
3298 """
3299 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003300 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003301 """
3302 crl = CRL()
3303 self.assertRaises(Error, crl.export, X509(), PKey())
3304
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003305 def test_add_revoked_keyword(self):
3306 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003307 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003308 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003309 """
3310 crl = CRL()
3311 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003312 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003313 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003314 crl.add_revoked(revoked=revoked)
3315 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3316
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003317 def test_export_wrong_args(self):
3318 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003319 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003320 four arguments, or with arguments other than the certificate,
3321 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003322 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003323 """
3324 crl = CRL()
3325 self.assertRaises(TypeError, crl.export)
3326 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003327 with pytest.raises(TypeError):
3328 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3329 with pytest.raises(TypeError):
3330 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3331 with pytest.raises(TypeError):
3332 crl.export(self.cert, None, FILETYPE_PEM, 10)
3333 with pytest.raises(TypeError):
3334 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003335 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3336
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003337 def test_export_unknown_filetype(self):
3338 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003339 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003340 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3341 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003342 """
3343 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003344 with pytest.raises(ValueError):
3345 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003346
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003347 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003348 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003349 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003350 in a :py:obj:`ValueError` being raised.
3351 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003352 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003353 self.assertRaises(
3354 ValueError,
3355 crl.export,
3356 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3357 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003358
Rick Dean536ba022009-07-24 23:57:27 -05003359 def test_get_revoked(self):
3360 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003361 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003362 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3363 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003364 """
3365 crl = CRL()
3366
3367 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003368 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003369 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003370 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003371 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003372 revoked.set_serial(b('100'))
3373 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003374 crl.add_revoked(revoked)
3375
3376 revs = crl.get_revoked()
3377 self.assertEqual(len(revs), 2)
3378 self.assertEqual(type(revs[0]), Revoked)
3379 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003380 self.assertEqual(revs[0].get_serial(), b('03AB'))
3381 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003382 self.assertEqual(revs[0].get_rev_date(), now)
3383 self.assertEqual(revs[1].get_rev_date(), now)
3384
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003385 def test_get_revoked_wrong_args(self):
3386 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003387 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3388 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003389 """
3390 crl = CRL()
3391 self.assertRaises(TypeError, crl.get_revoked, None)
3392 self.assertRaises(TypeError, crl.get_revoked, 1)
3393 self.assertRaises(TypeError, crl.get_revoked, "")
3394 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3395
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003396 def test_add_revoked_wrong_args(self):
3397 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003398 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3399 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003400 """
3401 crl = CRL()
3402 self.assertRaises(TypeError, crl.add_revoked)
3403 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3404 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3405
Rick Dean536ba022009-07-24 23:57:27 -05003406 def test_load_crl(self):
3407 """
3408 Load a known CRL and inspect its revocations. Both
3409 PEM and DER formats are loaded.
3410 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003411 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003412 revs = crl.get_revoked()
3413 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003414 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003415 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003416 self.assertEqual(revs[1].get_serial(), b('0100'))
3417 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003418
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003419 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003420 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003421 revs = crl.get_revoked()
3422 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003423 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003424 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003425 self.assertEqual(revs[1].get_serial(), b('0100'))
3426 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003427
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003428 def test_load_crl_wrong_args(self):
3429 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003430 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3431 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003432 """
3433 self.assertRaises(TypeError, load_crl)
3434 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3435 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3436
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003437 def test_load_crl_bad_filetype(self):
3438 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003439 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3440 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003441 """
3442 self.assertRaises(ValueError, load_crl, 100, crlData)
3443
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003444 def test_load_crl_bad_data(self):
3445 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003446 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3447 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003448 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003449 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003450
Dan Sully44e767a2016-06-04 18:05:27 -07003451 def test_get_issuer(self):
3452 """
3453 Load a known CRL and assert its issuer's common name is
3454 what we expect from the encoded crlData string.
3455 """
3456 crl = load_crl(FILETYPE_PEM, crlData)
3457 self.assertTrue(isinstance(crl.get_issuer(), X509Name))
3458 self.assertEqual(crl.get_issuer().CN, 'Testing Root CA')
3459
Dominic Chenf05b2122015-10-13 16:32:35 +00003460 def test_dump_crl(self):
3461 """
3462 The dumped CRL matches the original input.
3463 """
3464 crl = load_crl(FILETYPE_PEM, crlData)
3465 buf = dump_crl(FILETYPE_PEM, crl)
3466 assert buf == crlData
3467
Dan Sully44e767a2016-06-04 18:05:27 -07003468 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3469 """
3470 Create a CRL.
3471
3472 :param list[X509] certs: A list of certificates to revoke.
3473 :rtype: CRL
3474 """
3475 crl = CRL()
3476 for cert in certs:
3477 revoked = Revoked()
3478 # FIXME: This string splicing is an unfortunate implementation
3479 # detail that has been reported in
3480 # https://github.com/pyca/pyopenssl/issues/258
3481 serial = hex(cert.get_serial_number())[2:].encode('utf-8')
3482 revoked.set_serial(serial)
3483 revoked.set_reason(b'unspecified')
3484 revoked.set_rev_date(b'20140601000000Z')
3485 crl.add_revoked(revoked)
3486 crl.set_version(1)
3487 crl.set_lastUpdate(b'20140601000000Z')
3488 crl.set_nextUpdate(b'20180601000000Z')
3489 crl.sign(issuer_cert, issuer_key, digest=b'sha512')
3490 return crl
3491
3492 def test_verify_with_revoked(self):
3493 """
3494 :func:`verify_certificate` raises error when an intermediate
3495 certificate is revoked.
3496 """
3497 store = X509Store()
3498 store.add_cert(self.root_cert)
3499 store.add_cert(self.intermediate_cert)
3500 root_crl = self._make_test_crl(
3501 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3502 intermediate_crl = self._make_test_crl(
3503 self.intermediate_cert, self.intermediate_key, certs=[])
3504 store.add_crl(root_crl)
3505 store.add_crl(intermediate_crl)
3506 store.set_flags(
3507 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3508 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3509 e = self.assertRaises(
3510 X509StoreContextError, store_ctx.verify_certificate)
3511 self.assertEqual(e.args[0][2], 'certificate revoked')
3512
3513 def test_verify_with_missing_crl(self):
3514 """
3515 :func:`verify_certificate` raises error when an intermediate
3516 certificate's CRL is missing.
3517 """
3518 store = X509Store()
3519 store.add_cert(self.root_cert)
3520 store.add_cert(self.intermediate_cert)
3521 root_crl = self._make_test_crl(
3522 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3523 store.add_crl(root_crl)
3524 store.set_flags(
3525 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3526 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3527 e = self.assertRaises(
3528 X509StoreContextError, store_ctx.verify_certificate)
3529 self.assertEqual(e.args[0][2], 'unable to get certificate CRL')
3530 self.assertEqual(
3531 e.certificate.get_subject().CN, 'intermediate-service')
3532
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003533
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003534class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003535 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003536 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003537 """
3538 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3539 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003540 intermediate_server_cert = load_certificate(
3541 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003542
3543 def test_valid(self):
3544 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003545 :py:obj:`verify_certificate` returns ``None`` when called with a
3546 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003547 """
3548 store = X509Store()
3549 store.add_cert(self.root_cert)
3550 store.add_cert(self.intermediate_cert)
3551 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003552 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003553
3554 def test_reuse(self):
3555 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003556 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003557 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003558 """
3559 store = X509Store()
3560 store.add_cert(self.root_cert)
3561 store.add_cert(self.intermediate_cert)
3562 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003563 self.assertEqual(store_ctx.verify_certificate(), None)
3564 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003565
3566 def test_trusted_self_signed(self):
3567 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003568 :py:obj:`verify_certificate` returns ``None`` when called with a
3569 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003570 """
3571 store = X509Store()
3572 store.add_cert(self.root_cert)
3573 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003574 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003575
3576 def test_untrusted_self_signed(self):
3577 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003578 :py:obj:`verify_certificate` raises error when a self-signed
3579 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003580 """
3581 store = X509Store()
3582 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003583 with pytest.raises(X509StoreContextError) as exc:
3584 store_ctx.verify_certificate()
3585
3586 assert exc.value.args[0][2] == 'self signed certificate'
3587 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003588
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003589 def test_invalid_chain_no_root(self):
3590 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003591 :py:obj:`verify_certificate` raises error when a root certificate is
3592 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003593 """
3594 store = X509Store()
3595 store.add_cert(self.intermediate_cert)
3596 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003597
3598 with pytest.raises(X509StoreContextError) as exc:
3599 store_ctx.verify_certificate()
3600
3601 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3602 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003603
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003604 def test_invalid_chain_no_intermediate(self):
3605 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003606 :py:obj:`verify_certificate` raises error when an intermediate
3607 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003608 """
3609 store = X509Store()
3610 store.add_cert(self.root_cert)
3611 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003612
Alex Gaynor85b49702015-09-05 16:30:59 -04003613 with pytest.raises(X509StoreContextError) as exc:
3614 store_ctx.verify_certificate()
3615
3616 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3617 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003618
Stephen Holsapple46a09252015-02-12 14:45:43 -08003619 def test_modification_pre_verify(self):
3620 """
3621 :py:obj:`verify_certificate` can use a store context modified after
3622 instantiation.
3623 """
3624 store_bad = X509Store()
3625 store_bad.add_cert(self.intermediate_cert)
3626 store_good = X509Store()
3627 store_good.add_cert(self.root_cert)
3628 store_good.add_cert(self.intermediate_cert)
3629 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003630
3631 with pytest.raises(X509StoreContextError) as exc:
3632 store_ctx.verify_certificate()
3633
3634 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3635 assert exc.value.certificate.get_subject().CN == 'intermediate'
3636
Stephen Holsapple46a09252015-02-12 14:45:43 -08003637 store_ctx.set_store(store_good)
3638 self.assertEqual(store_ctx.verify_certificate(), None)
3639
3640
James Yonan7c2e5d32010-02-27 05:45:50 -07003641class SignVerifyTests(TestCase):
3642 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003643 Tests for :py:obj:`OpenSSL.crypto.sign` and
3644 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003645 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003646
James Yonan7c2e5d32010-02-27 05:45:50 -07003647 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003648 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003649 :py:obj:`sign` generates a cryptographic signature which
3650 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003651 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003652 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003653 "It was a bright cold day in April, and the clocks were striking "
3654 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3655 "effort to escape the vile wind, slipped quickly through the "
3656 "glass doors of Victory Mansions, though not quickly enough to "
3657 "prevent a swirl of gritty dust from entering along with him.")
3658
3659 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003660 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003661 # verify the content with this cert
3662 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3663 # certificate unrelated to priv_key, used to trigger an error
3664 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003665
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003666 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003667 sig = sign(priv_key, content, digest)
3668
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003669 # Verify the signature of content, will throw an exception if
3670 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003671 verify(good_cert, sig, content, digest)
3672
3673 # This should fail because the certificate doesn't match the
3674 # private key that was used to sign the content.
3675 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3676
3677 # This should fail because we've "tainted" the content after
3678 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003679 self.assertRaises(
3680 Error, verify,
3681 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003682
3683 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003684 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003685 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003686 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003687 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003688
Abraham Martinc5484ba2015-03-25 15:33:05 +00003689 def test_sign_verify_with_text(self):
3690 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003691 :py:obj:`sign` generates a cryptographic signature which
3692 :py:obj:`verify` can check. Deprecation warnings raised because using
3693 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003694 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003695 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003696 b"It was a bright cold day in April, and the clocks were striking "
3697 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3698 b"effort to escape the vile wind, slipped quickly through the "
3699 b"glass doors of Victory Mansions, though not quickly enough to "
3700 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003701 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003702
3703 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3704 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3705 for digest in ['md5', 'sha1']:
3706 with catch_warnings(record=True) as w:
3707 simplefilter("always")
3708 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003709
3710 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003711 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003712 WARNING_TYPE_EXPECTED
3713 ),
3714 str(w[-1].message)
3715 )
3716 self.assertIs(w[-1].category, DeprecationWarning)
3717
Abraham Martinc5484ba2015-03-25 15:33:05 +00003718 with catch_warnings(record=True) as w:
3719 simplefilter("always")
3720 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003721
3722 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003723 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003724 WARNING_TYPE_EXPECTED
3725 ),
3726 str(w[-1].message)
3727 )
3728 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003729
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003730 def test_sign_nulls(self):
3731 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003732 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003733 """
3734 content = b("Watch out! \0 Did you see it?")
3735 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3736 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3737 sig = sign(priv_key, content, "sha1")
3738 verify(good_cert, sig, content, "sha1")
3739
Colleen Murphye09399b2016-03-01 17:40:49 -08003740 def test_sign_with_large_key(self):
3741 """
3742 :py:obj:`sign` produces a signature for a string when using a long key.
3743 """
3744 content = b(
3745 "It was a bright cold day in April, and the clocks were striking "
3746 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3747 "effort to escape the vile wind, slipped quickly through the "
3748 "glass doors of Victory Mansions, though not quickly enough to "
3749 "prevent a swirl of gritty dust from entering along with him.")
3750
3751 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3752 sign(priv_key, content, "sha1")
3753
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003754
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003755class EllipticCurveTests(TestCase):
3756 """
3757 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3758 :py:obj:`get_elliptic_curves`.
3759 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003760
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003761 def test_set(self):
3762 """
3763 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3764 """
3765 self.assertIsInstance(get_elliptic_curves(), set)
3766
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003767 def test_some_curves(self):
3768 """
3769 If :py:mod:`cryptography` has elliptic curve support then the set
3770 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3771 it.
3772
3773 There could be an OpenSSL that violates this assumption. If so, this
3774 test will fail and we'll find out.
3775 """
3776 curves = get_elliptic_curves()
3777 if lib.Cryptography_HAS_EC:
3778 self.assertTrue(curves)
3779 else:
3780 self.assertFalse(curves)
3781
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003782 def test_a_curve(self):
3783 """
3784 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3785 supported curve.
3786 """
3787 curves = get_elliptic_curves()
3788 if curves:
3789 curve = next(iter(curves))
3790 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3791 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003792 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003793
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003794 def test_not_a_curve(self):
3795 """
3796 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3797 with a name which does not identify a supported curve.
3798 """
3799 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003800 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003801
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003802 def test_repr(self):
3803 """
3804 The string representation of a curve object includes simply states the
3805 object is a curve and what its name is.
3806 """
3807 curves = get_elliptic_curves()
3808 if curves:
3809 curve = next(iter(curves))
3810 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3811
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003812 def test_to_EC_KEY(self):
3813 """
3814 The curve object can export a version of itself as an EC_KEY* via the
3815 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3816 """
3817 curves = get_elliptic_curves()
3818 if curves:
3819 curve = next(iter(curves))
3820 # It's not easy to assert anything about this object. However, see
3821 # leakcheck/crypto.py for a test that demonstrates it at least does
3822 # not leak memory.
3823 curve._to_EC_KEY()
3824
3825
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003826class EllipticCurveFactory(object):
3827 """
3828 A helper to get the names of two curves.
3829 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003830
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003831 def __init__(self):
3832 curves = iter(get_elliptic_curves())
3833 try:
3834 self.curve_name = next(curves).name
3835 self.another_curve_name = next(curves).name
3836 except StopIteration:
3837 self.curve_name = self.another_curve_name = None
3838
3839
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003840class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3841 """
3842 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3843 """
3844 curve_factory = EllipticCurveFactory()
3845
3846 if curve_factory.curve_name is None:
3847 skip = "There are no curves available there can be no curve objects."
3848
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003849 def anInstance(self):
3850 """
3851 Get the curve object for an arbitrary curve supported by the system.
3852 """
3853 return get_elliptic_curve(self.curve_factory.curve_name)
3854
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003855 def anotherInstance(self):
3856 """
3857 Get the curve object for an arbitrary curve supported by the system -
3858 but not the one returned by C{anInstance}.
3859 """
3860 return get_elliptic_curve(self.curve_factory.another_curve_name)
3861
3862
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003863class EllipticCurveHashTests(TestCase):
3864 """
3865 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3866 as an item in a :py:type:`dict` or :py:type:`set`).
3867 """
3868 curve_factory = EllipticCurveFactory()
3869
3870 if curve_factory.curve_name is None:
3871 skip = "There are no curves available there can be no curve objects."
3872
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003873 def test_contains(self):
3874 """
3875 The ``in`` operator reports that a :py:type:`set` containing a curve
3876 does contain that curve.
3877 """
3878 curve = get_elliptic_curve(self.curve_factory.curve_name)
3879 curves = set([curve])
3880 self.assertIn(curve, curves)
3881
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003882 def test_does_not_contain(self):
3883 """
3884 The ``in`` operator reports that a :py:type:`set` not containing a
3885 curve does not contain that curve.
3886 """
3887 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003888 curves = set([
3889 get_elliptic_curve(self.curve_factory.another_curve_name)
3890 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003891 self.assertNotIn(curve, curves)
3892
3893
Rick Dean5b7b6372009-04-01 11:34:06 -05003894if __name__ == '__main__':
3895 main()