blob: 2febb95108c048390ea618c0135911eb7b6d4b12 [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
805 # XXX RSA generation for small values of bits is fairly buggy in a wide
806 # range of OpenSSL versions. I need to figure out what the safe lower
807 # bound for a reasonable number of OpenSSL versions is and explicitly
808 # check for that in the wrapper. The failure behavior is typically an
809 # infinite loop inside OpenSSL.
810
811 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500812
813 # XXX DSA generation seems happy with any number of bits. The DSS
814 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
815 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500816 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500817 # So, it doesn't seem possible to make generate_key fail for
818 # TYPE_DSA with a bits argument which is at least an int.
819
820 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
821
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500822 def test_rsaGeneration(self):
823 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900824 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
825 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500826 """
827 bits = 128
828 key = PKey()
829 key.generate_key(TYPE_RSA, bits)
830 self.assertEqual(key.type(), TYPE_RSA)
831 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400832 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500833
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500834 def test_dsaGeneration(self):
835 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900836 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
837 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500838 """
839 # 512 is a magic number. The DSS (Digital Signature Standard)
840 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
841 # will silently promote any value below 512 to 512.
842 bits = 512
843 key = PKey()
844 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800845 # self.assertEqual(key.type(), TYPE_DSA)
846 # self.assertEqual(key.bits(), bits)
847 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500848
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500849 def test_regeneration(self):
850 """
Alex Gaynor31287502015-09-05 16:11:27 -0400851 :py:meth:`PKeyType.generate_key` can be called multiple times on the
852 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500853 """
854 key = PKey()
855 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400856 key.generate_key(type, bits)
857 self.assertEqual(key.type(), type)
858 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500859
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400860 def test_inconsistentKey(self):
861 """
Alex Gaynor31287502015-09-05 16:11:27 -0400862 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
863 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400864 """
865 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400866 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400867
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400868 def test_check_wrong_args(self):
869 """
Alex Gaynor31287502015-09-05 16:11:27 -0400870 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
871 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400872 """
873 self.assertRaises(TypeError, PKey().check, None)
874 self.assertRaises(TypeError, PKey().check, object())
875 self.assertRaises(TypeError, PKey().check, 1)
876
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400877 def test_check_public_key(self):
878 """
879 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
880 part of the key is available.
881 """
882 # A trick to get a public-only key
883 key = PKey()
884 key.generate_key(TYPE_RSA, 512)
885 cert = X509()
886 cert.set_pubkey(key)
887 pub = cert.get_pubkey()
888 self.assertRaises(TypeError, pub.check)
889
890
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400891class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500892 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900893 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500894 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400895
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500896 def _x509name(self, **attrs):
897 # XXX There's no other way to get a new X509Name yet.
898 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400899 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400900
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500901 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400902 def key(attr):
903 return attr[1]
904 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500905 for k, v in attrs:
906 setattr(name, k, v)
907 return name
908
Rick Deane15b1472009-07-09 15:53:42 -0500909 def test_type(self):
910 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900911 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500912 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400913 self.assertIdentical(X509Name, X509NameType)
914 self.assertEqual(X509NameType.__name__, 'X509Name')
915 self.assertTrue(isinstance(X509NameType, type))
916
Rick Deane15b1472009-07-09 15:53:42 -0500917 name = self._x509name()
918 self.assertTrue(
919 isinstance(name, X509NameType),
920 "%r is of type %r, should be %r" % (
921 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500922
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400923 def test_onlyStringAttributes(self):
924 """
Alex Gaynor31287502015-09-05 16:11:27 -0400925 Attempting to set a non-:py:data:`str` attribute name on an
926 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
927 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400928 """
929 name = self._x509name()
930 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400931 # rejected. Sorry, you're wrong. unicode is automatically converted
932 # to str outside of the control of X509Name, so there's no way to
933 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800934
Alex Gaynor31287502015-09-05 16:11:27 -0400935 # Also, this used to test str subclasses, but that test is less
936 # relevant now that the implementation is in Python instead of C. Also
937 # PyPy automatically converts str subclasses to str when they are
938 # passed to setattr, so we can't test it on PyPy. Apparently CPython
939 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400940 self.assertRaises(TypeError, setattr, name, None, "hello")
941 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400942
943 def test_setInvalidAttribute(self):
944 """
Alex Gaynor31287502015-09-05 16:11:27 -0400945 Attempting to set any attribute name on an :py:class:`X509NameType`
946 instance for which no corresponding NID is defined causes
947 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400948 """
949 name = self._x509name()
950 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
951
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500952 def test_attributes(self):
953 """
Alex Gaynor31287502015-09-05 16:11:27 -0400954 :py:class:`X509NameType` instances have attributes for each standard
955 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500956 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500957 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500958 name.commonName = "foo"
959 self.assertEqual(name.commonName, "foo")
960 self.assertEqual(name.CN, "foo")
961 name.CN = "baz"
962 self.assertEqual(name.commonName, "baz")
963 self.assertEqual(name.CN, "baz")
964 name.commonName = "bar"
965 self.assertEqual(name.commonName, "bar")
966 self.assertEqual(name.CN, "bar")
967 name.CN = "quux"
968 self.assertEqual(name.commonName, "quux")
969 self.assertEqual(name.CN, "quux")
970
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500971 def test_copy(self):
972 """
Alex Gaynor31287502015-09-05 16:11:27 -0400973 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
974 with all the same attributes as an existing :py:class:`X509NameType`
975 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500976 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500977 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500978
979 copy = X509Name(name)
980 self.assertEqual(copy.commonName, "foo")
981 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500982
983 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500984 copy.commonName = "baz"
985 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500986
987 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500988 name.emailAddress = "quux@example.com"
989 self.assertEqual(copy.emailAddress, "bar@example.com")
990
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500991 def test_repr(self):
992 """
Alex Gaynor31287502015-09-05 16:11:27 -0400993 :py:func:`repr` passed an :py:class:`X509NameType` instance should
994 return a string containing a description of the type and the NIDs which
995 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500996 """
997 name = self._x509name(commonName="foo", emailAddress="bar")
998 self.assertEqual(
999 repr(name),
1000 "<X509Name object '/emailAddress=bar/CN=foo'>")
1001
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001002 def test_comparison(self):
1003 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001004 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001005 """
1006 def _equality(a, b, assertTrue, assertFalse):
1007 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
1008 assertFalse(a != b)
1009 assertTrue(b == a)
1010 assertFalse(b != a)
1011
1012 def assertEqual(a, b):
1013 _equality(a, b, self.assertTrue, self.assertFalse)
1014
1015 # Instances compare equal to themselves.
1016 name = self._x509name()
1017 assertEqual(name, name)
1018
1019 # Empty instances should compare equal to each other.
1020 assertEqual(self._x509name(), self._x509name())
1021
1022 # Instances with equal NIDs should compare equal to each other.
1023 assertEqual(self._x509name(commonName="foo"),
1024 self._x509name(commonName="foo"))
1025
1026 # Instance with equal NIDs set using different aliases should compare
1027 # equal to each other.
1028 assertEqual(self._x509name(commonName="foo"),
1029 self._x509name(CN="foo"))
1030
1031 # Instances with more than one NID with the same values should compare
1032 # equal to each other.
1033 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
1034 self._x509name(commonName="foo", OU="bar"))
1035
1036 def assertNotEqual(a, b):
1037 _equality(a, b, self.assertFalse, self.assertTrue)
1038
1039 # Instances with different values for the same NID should not compare
1040 # equal to each other.
1041 assertNotEqual(self._x509name(CN="foo"),
1042 self._x509name(CN="bar"))
1043
1044 # Instances with different NIDs should not compare equal to each other.
1045 assertNotEqual(self._x509name(CN="foo"),
1046 self._x509name(OU="foo"))
1047
1048 def _inequality(a, b, assertTrue, assertFalse):
1049 assertTrue(a < b)
1050 assertTrue(a <= b)
1051 assertTrue(b > a)
1052 assertTrue(b >= a)
1053 assertFalse(a > b)
1054 assertFalse(a >= b)
1055 assertFalse(b < a)
1056 assertFalse(b <= a)
1057
1058 def assertLessThan(a, b):
1059 _inequality(a, b, self.assertTrue, self.assertFalse)
1060
1061 # An X509Name with a NID with a value which sorts less than the value
1062 # of the same NID on another X509Name compares less than the other
1063 # X509Name.
1064 assertLessThan(self._x509name(CN="abc"),
1065 self._x509name(CN="def"))
1066
1067 def assertGreaterThan(a, b):
1068 _inequality(a, b, self.assertFalse, self.assertTrue)
1069
1070 # An X509Name with a NID with a value which sorts greater than the
1071 # value of the same NID on another X509Name compares greater than the
1072 # other X509Name.
1073 assertGreaterThan(self._x509name(CN="def"),
1074 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001075
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001076 def test_hash(self):
1077 """
Alex Gaynor31287502015-09-05 16:11:27 -04001078 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1079 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001080 """
1081 a = self._x509name(CN="foo")
1082 b = self._x509name(CN="foo")
1083 self.assertEqual(a.hash(), b.hash())
1084 a.CN = "bar"
1085 self.assertNotEqual(a.hash(), b.hash())
1086
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001087 def test_der(self):
1088 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001089 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001090 """
1091 a = self._x509name(CN="foo", C="US")
1092 self.assertEqual(
1093 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001094 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001095 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001096
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001097 def test_get_components(self):
1098 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001099 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1100 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001101 giving the NIDs and associated values which make up the name.
1102 """
1103 a = self._x509name()
1104 self.assertEqual(a.get_components(), [])
1105 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001106 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001107 a.organizationalUnitName = "bar"
1108 self.assertEqual(
1109 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001110 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001111
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001112 def test_load_nul_byte_attribute(self):
1113 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001114 An :py:class:`OpenSSL.crypto.X509Name` from an
1115 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001116 NUL byte in the value of one of its attributes.
1117 """
1118 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1119 subject = cert.get_subject()
1120 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001121 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001122
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001123 def test_setAttributeFailure(self):
1124 """
1125 If the value of an attribute cannot be set for some reason then
1126 :py:class:`OpenSSL.crypto.Error` is raised.
1127 """
1128 name = self._x509name()
1129 # This value is too long
1130 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1131
1132
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001133class _PKeyInteractionTestsMixin:
1134 """
1135 Tests which involve another thing and a PKey.
1136 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001137
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001138 def signable(self):
1139 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001140 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1141 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001142 """
1143 raise NotImplementedError()
1144
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001145 def test_signWithUngenerated(self):
1146 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001147 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1148 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001149 """
1150 request = self.signable()
1151 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001152 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001153
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001154 def test_signWithPublicKey(self):
1155 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001156 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1157 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001158 """
1159 request = self.signable()
1160 key = PKey()
1161 key.generate_key(TYPE_RSA, 512)
1162 request.set_pubkey(key)
1163 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001164 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001165
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001166 def test_signWithUnknownDigest(self):
1167 """
Alex Gaynor31287502015-09-05 16:11:27 -04001168 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1169 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001170 """
1171 request = self.signable()
1172 key = PKey()
1173 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001174 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001175
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001176 def test_sign(self):
1177 """
Alex Gaynor31287502015-09-05 16:11:27 -04001178 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1179 valid digest function. :py:meth:`X509Req.verify` can be used to check
1180 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001181 """
1182 request = self.signable()
1183 key = PKey()
1184 key.generate_key(TYPE_RSA, 512)
1185 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001186 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001187 # If the type has a verify method, cover that too.
1188 if getattr(request, 'verify', None) is not None:
1189 pub = request.get_pubkey()
1190 self.assertTrue(request.verify(pub))
1191 # Make another key that won't verify.
1192 key = PKey()
1193 key.generate_key(TYPE_RSA, 512)
1194 self.assertRaises(Error, request.verify, key)
1195
1196
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001197class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001198 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001199 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001200 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001201
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001202 def signable(self):
1203 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001204 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001205 """
1206 return X509Req()
1207
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001208 def test_type(self):
1209 """
Alex Gaynor31287502015-09-05 16:11:27 -04001210 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1211 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001212 """
1213 self.assertIdentical(X509Req, X509ReqType)
1214 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001215
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001216 def test_construction(self):
1217 """
Alex Gaynor31287502015-09-05 16:11:27 -04001218 :py:obj:`X509Req` takes no arguments and returns an
1219 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001220 """
1221 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001222 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001223
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001224 def test_version(self):
1225 """
Alex Gaynor31287502015-09-05 16:11:27 -04001226 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1227 certificate request. :py:obj:`X509ReqType.get_version` returns the
1228 X.509 version of the certificate request. The initial value of the
1229 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001230 """
1231 request = X509Req()
1232 self.assertEqual(request.get_version(), 0)
1233 request.set_version(1)
1234 self.assertEqual(request.get_version(), 1)
1235 request.set_version(3)
1236 self.assertEqual(request.get_version(), 3)
1237
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001238 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001239 """
Alex Gaynor31287502015-09-05 16:11:27 -04001240 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1241 with the wrong number of arguments or with a non-:py:obj:`int`
1242 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1243 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001244 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001245 request = X509Req()
1246 self.assertRaises(TypeError, request.set_version)
1247 self.assertRaises(TypeError, request.set_version, "foo")
1248 self.assertRaises(TypeError, request.set_version, 1, 2)
1249 self.assertRaises(TypeError, request.get_version, None)
1250
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001251 def test_get_subject(self):
1252 """
Alex Gaynor31287502015-09-05 16:11:27 -04001253 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1254 subject of the request and which is valid even after the request object
1255 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001256 """
1257 request = X509Req()
1258 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001259 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001260 subject.commonName = "foo"
1261 self.assertEqual(request.get_subject().commonName, "foo")
1262 del request
1263 subject.commonName = "bar"
1264 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001265
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001266 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001267 """
Alex Gaynor31287502015-09-05 16:11:27 -04001268 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1269 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001270 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001271 request = X509Req()
1272 self.assertRaises(TypeError, request.get_subject, None)
1273
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001274 def test_add_extensions(self):
1275 """
Alex Gaynor31287502015-09-05 16:11:27 -04001276 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1277 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001278 """
1279 request = X509Req()
1280 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001281 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001282 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001283 self.assertEqual(len(exts), 1)
1284 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1285 self.assertEqual(exts[0].get_critical(), 1)
1286 self.assertEqual(exts[0].get_data(), b('0\x00'))
1287
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001288 def test_get_extensions(self):
1289 """
1290 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1291 extensions added to this X509 request.
1292 """
1293 request = X509Req()
1294 exts = request.get_extensions()
1295 self.assertEqual(exts, [])
1296 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001297 X509Extension(b('basicConstraints'), True, b('CA:true')),
1298 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001299 exts = request.get_extensions()
1300 self.assertEqual(len(exts), 2)
1301 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1302 self.assertEqual(exts[0].get_critical(), 1)
1303 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1304 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1305 self.assertEqual(exts[1].get_critical(), 0)
1306 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001307
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001308 def test_add_extensions_wrong_args(self):
1309 """
Alex Gaynor31287502015-09-05 16:11:27 -04001310 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1311 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1312 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1313 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001314 """
1315 request = X509Req()
1316 self.assertRaises(TypeError, request.add_extensions)
1317 self.assertRaises(TypeError, request.add_extensions, object())
1318 self.assertRaises(ValueError, request.add_extensions, [object()])
1319 self.assertRaises(TypeError, request.add_extensions, [], None)
1320
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001321 def test_verify_wrong_args(self):
1322 """
1323 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1324 arguments or more than one argument or if passed anything other than a
1325 :py:obj:`PKey` instance as its single argument.
1326 """
1327 request = X509Req()
1328 self.assertRaises(TypeError, request.verify)
1329 self.assertRaises(TypeError, request.verify, object())
1330 self.assertRaises(TypeError, request.verify, PKey(), object())
1331
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001332 def test_verify_uninitialized_key(self):
1333 """
Alex Gaynor31287502015-09-05 16:11:27 -04001334 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1335 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001336 """
1337 request = X509Req()
1338 pkey = PKey()
1339 self.assertRaises(Error, request.verify, pkey)
1340
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001341 def test_verify_wrong_key(self):
1342 """
Alex Gaynor31287502015-09-05 16:11:27 -04001343 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1344 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1345 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001346 """
1347 request = X509Req()
1348 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001349 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001350 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1351 self.assertRaises(Error, request.verify, another_pkey)
1352
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001353 def test_verify_success(self):
1354 """
1355 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001356 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1357 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001358 """
1359 request = X509Req()
1360 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001361 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001362 self.assertEqual(True, request.verify(pkey))
1363
1364
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001365class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001366 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001367 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001368 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001369 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001370
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001371 extpem = """
1372-----BEGIN CERTIFICATE-----
1373MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1374BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1375eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1376MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1377aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1378hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1379Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1380zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1381hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1382TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
138303HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1384MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1385b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1386MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1387uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1388WpOdIpB8KksUTCzV591Nr1wd
1389-----END CERTIFICATE-----
1390 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001391
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001392 def signable(self):
1393 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001394 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001395 """
1396 return X509()
1397
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001398 def test_type(self):
1399 """
Alex Gaynor31287502015-09-05 16:11:27 -04001400 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1401 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001402 """
1403 self.assertIdentical(X509, X509Type)
1404 self.assertConsistentType(X509, 'X509')
1405
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001406 def test_construction(self):
1407 """
Alex Gaynor31287502015-09-05 16:11:27 -04001408 :py:obj:`X509` takes no arguments and returns an instance of
1409 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001410 """
1411 certificate = X509()
1412 self.assertTrue(
1413 isinstance(certificate, X509Type),
1414 "%r is of type %r, should be %r" % (certificate,
1415 type(certificate),
1416 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001417 self.assertEqual(type(X509Type).__name__, 'type')
1418 self.assertEqual(type(certificate).__name__, 'X509')
1419 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001420 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001421
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001422 def test_get_version_wrong_args(self):
1423 """
Alex Gaynor31287502015-09-05 16:11:27 -04001424 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1425 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001426 """
1427 cert = X509()
1428 self.assertRaises(TypeError, cert.get_version, None)
1429
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001430 def test_set_version_wrong_args(self):
1431 """
Alex Gaynor31287502015-09-05 16:11:27 -04001432 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1433 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001434 """
1435 cert = X509()
1436 self.assertRaises(TypeError, cert.set_version)
1437 self.assertRaises(TypeError, cert.set_version, None)
1438 self.assertRaises(TypeError, cert.set_version, 1, None)
1439
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001440 def test_version(self):
1441 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001442 :py:obj:`X509.set_version` sets the certificate version number.
1443 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001444 """
1445 cert = X509()
1446 cert.set_version(1234)
1447 self.assertEquals(cert.get_version(), 1234)
1448
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001449 def test_get_serial_number_wrong_args(self):
1450 """
Alex Gaynor31287502015-09-05 16:11:27 -04001451 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1452 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001453 """
1454 cert = X509()
1455 self.assertRaises(TypeError, cert.get_serial_number, None)
1456
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001457 def test_serial_number(self):
1458 """
Alex Gaynor31287502015-09-05 16:11:27 -04001459 The serial number of an :py:obj:`X509Type` can be retrieved and
1460 modified with :py:obj:`X509Type.get_serial_number` and
1461 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001462 """
1463 certificate = X509()
1464 self.assertRaises(TypeError, certificate.set_serial_number)
1465 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1466 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1467 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1468 self.assertEqual(certificate.get_serial_number(), 0)
1469 certificate.set_serial_number(1)
1470 self.assertEqual(certificate.get_serial_number(), 1)
1471 certificate.set_serial_number(2 ** 32 + 1)
1472 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1473 certificate.set_serial_number(2 ** 64 + 1)
1474 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001475 certificate.set_serial_number(2 ** 128 + 1)
1476 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1477
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001478 def _setBoundTest(self, which):
1479 """
Alex Gaynor31287502015-09-05 16:11:27 -04001480 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1481 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1482 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001483 """
1484 certificate = X509()
1485 set = getattr(certificate, 'set_not' + which)
1486 get = getattr(certificate, 'get_not' + which)
1487
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001488 # Starts with no value.
1489 self.assertEqual(get(), None)
1490
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001491 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001492 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001493 set(when)
1494 self.assertEqual(get(), when)
1495
1496 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001497 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001498 set(when)
1499 self.assertEqual(get(), when)
1500
1501 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001502 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001503 set(when)
1504 self.assertEqual(get(), when)
1505
1506 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001507 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001508
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001509 # The wrong number of arguments results in a TypeError.
1510 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001511 with pytest.raises(TypeError):
1512 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001513 self.assertRaises(TypeError, get, b("foo bar"))
1514
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001515 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001516
1517 def test_set_notBefore(self):
1518 """
Alex Gaynor31287502015-09-05 16:11:27 -04001519 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1520 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1521 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001522 """
1523 self._setBoundTest("Before")
1524
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001525 def test_set_notAfter(self):
1526 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001527 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001528 GENERALIZEDTIME and sets the end of the certificate's validity period
1529 to it.
1530 """
1531 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001532
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001533 def test_get_notBefore(self):
1534 """
Alex Gaynor31287502015-09-05 16:11:27 -04001535 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1536 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001537 internally.
1538 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001539 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001540 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001541
Rick Dean38a05c82009-07-18 01:41:30 -05001542 def test_get_notAfter(self):
1543 """
Alex Gaynor31287502015-09-05 16:11:27 -04001544 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1545 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001546 internally.
1547 """
1548 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001549 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001550
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001551 def test_gmtime_adj_notBefore_wrong_args(self):
1552 """
Alex Gaynor31287502015-09-05 16:11:27 -04001553 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1554 called with the wrong number of arguments or a non-:py:obj:`int`
1555 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001556 """
1557 cert = X509()
1558 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1559 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1560 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1561
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001562 def test_gmtime_adj_notBefore(self):
1563 """
Alex Gaynor31287502015-09-05 16:11:27 -04001564 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1565 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001566 """
1567 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001568 not_before_min = (
1569 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1570 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001571 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001572 not_before = datetime.strptime(
1573 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1574 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001575 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1576 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001577
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001578 def test_gmtime_adj_notAfter_wrong_args(self):
1579 """
Alex Gaynor31287502015-09-05 16:11:27 -04001580 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1581 called with the wrong number of arguments or a non-:py:obj:`int`
1582 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001583 """
1584 cert = X509()
1585 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1586 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1587 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1588
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001589 def test_gmtime_adj_notAfter(self):
1590 """
Alex Gaynor31287502015-09-05 16:11:27 -04001591 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1592 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001593 """
1594 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001595 not_after_min = (
1596 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1597 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001598 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001599 not_after = datetime.strptime(
1600 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1601 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001602 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1603 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001604
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001605 def test_has_expired_wrong_args(self):
1606 """
Alex Gaynor31287502015-09-05 16:11:27 -04001607 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1608 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001609 """
1610 cert = X509()
1611 self.assertRaises(TypeError, cert.has_expired, None)
1612
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001613 def test_has_expired(self):
1614 """
Alex Gaynor31287502015-09-05 16:11:27 -04001615 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1616 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001617 """
1618 cert = X509()
1619 cert.gmtime_adj_notAfter(-1)
1620 self.assertTrue(cert.has_expired())
1621
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001622 def test_has_not_expired(self):
1623 """
Alex Gaynor31287502015-09-05 16:11:27 -04001624 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1625 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001626 """
1627 cert = X509()
1628 cert.gmtime_adj_notAfter(2)
1629 self.assertFalse(cert.has_expired())
1630
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001631 def test_root_has_not_expired(self):
1632 """
Alex Gaynor31287502015-09-05 16:11:27 -04001633 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1634 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001635 """
1636 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1637 self.assertFalse(cert.has_expired())
1638
Rick Dean38a05c82009-07-18 01:41:30 -05001639 def test_digest(self):
1640 """
Alex Gaynor31287502015-09-05 16:11:27 -04001641 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1642 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001643 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001644 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001645 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001646 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1647 # actually matters to the assertion (ie, another arbitrary, good
1648 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001649 # Digest verified with the command:
1650 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001651 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001652 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001653
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001654 def _extcert(self, pkey, extensions):
1655 cert = X509()
1656 cert.set_pubkey(pkey)
1657 cert.get_subject().commonName = "Unit Tests"
1658 cert.get_issuer().commonName = "Unit Tests"
1659 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1660 cert.set_notBefore(when)
1661 cert.set_notAfter(when)
1662
1663 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001664 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001665 return load_certificate(
1666 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1667
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001668 def test_extension_count(self):
1669 """
Alex Gaynor31287502015-09-05 16:11:27 -04001670 :py:obj:`X509.get_extension_count` returns the number of extensions
1671 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001672 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001673 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001674 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1675 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001676 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001677 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001678
1679 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001680 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001681 self.assertEqual(c.get_extension_count(), 0)
1682
1683 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001684 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001685 self.assertEqual(c.get_extension_count(), 1)
1686
1687 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001688 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001689 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001690
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001691 def test_get_extension(self):
1692 """
Alex Gaynor31287502015-09-05 16:11:27 -04001693 :py:obj:`X509.get_extension` takes an integer and returns an
1694 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001695 """
1696 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001697 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1698 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001699 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001700 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001701
1702 cert = self._extcert(pkey, [ca, key, subjectAltName])
1703
1704 ext = cert.get_extension(0)
1705 self.assertTrue(isinstance(ext, X509Extension))
1706 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001707 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001708
1709 ext = cert.get_extension(1)
1710 self.assertTrue(isinstance(ext, X509Extension))
1711 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001712 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001713
1714 ext = cert.get_extension(2)
1715 self.assertTrue(isinstance(ext, X509Extension))
1716 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001717 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001718
1719 self.assertRaises(IndexError, cert.get_extension, -1)
1720 self.assertRaises(IndexError, cert.get_extension, 4)
1721 self.assertRaises(TypeError, cert.get_extension, "hello")
1722
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001723 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001724 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001725 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001726 bytes and this value is reflected in the string representation of the
1727 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001728 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001729 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001730
1731 ext = cert.get_extension(3)
1732 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001733 self.assertEqual(
1734 b("DNS:altnull.python.org\x00example.com, "
1735 "email:null@python.org\x00user@example.org, "
1736 "URI:http://null.python.org\x00http://example.org, "
1737 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1738 b(str(ext)))
1739
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001740 def test_invalid_digest_algorithm(self):
1741 """
Alex Gaynor31287502015-09-05 16:11:27 -04001742 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1743 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001744 """
1745 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001746 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001747
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001748 def test_get_subject_wrong_args(self):
1749 """
Alex Gaynor31287502015-09-05 16:11:27 -04001750 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1751 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001752 """
1753 cert = X509()
1754 self.assertRaises(TypeError, cert.get_subject, None)
1755
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001756 def test_get_subject(self):
1757 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001758 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001759 """
1760 cert = load_certificate(FILETYPE_PEM, self.pemData)
1761 subj = cert.get_subject()
1762 self.assertTrue(isinstance(subj, X509Name))
1763 self.assertEquals(
1764 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001765 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1766 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001767
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001768 def test_set_subject_wrong_args(self):
1769 """
Alex Gaynor31287502015-09-05 16:11:27 -04001770 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1771 the wrong number of arguments or an argument not of type
1772 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001773 """
1774 cert = X509()
1775 self.assertRaises(TypeError, cert.set_subject)
1776 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001777 with pytest.raises(TypeError):
1778 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001779
1780 def test_set_subject(self):
1781 """
Alex Gaynor31287502015-09-05 16:11:27 -04001782 :py:obj:`X509.set_subject` changes the subject of the certificate to
1783 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001784 """
1785 cert = X509()
1786 name = cert.get_subject()
1787 name.C = 'AU'
1788 name.O = 'Unit Tests'
1789 cert.set_subject(name)
1790 self.assertEquals(
1791 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001792 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001793
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001794 def test_get_issuer_wrong_args(self):
1795 """
Alex Gaynor31287502015-09-05 16:11:27 -04001796 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1797 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001798 """
1799 cert = X509()
1800 self.assertRaises(TypeError, cert.get_issuer, None)
1801
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001802 def test_get_issuer(self):
1803 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001804 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001805 """
1806 cert = load_certificate(FILETYPE_PEM, self.pemData)
1807 subj = cert.get_issuer()
1808 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001809 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001810 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001811 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001812 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1813 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001814
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001815 def test_set_issuer_wrong_args(self):
1816 """
Alex Gaynor31287502015-09-05 16:11:27 -04001817 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1818 the wrong number of arguments or an argument not of type
1819 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001820 """
1821 cert = X509()
1822 self.assertRaises(TypeError, cert.set_issuer)
1823 self.assertRaises(TypeError, cert.set_issuer, None)
1824 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1825
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001826 def test_set_issuer(self):
1827 """
Alex Gaynor31287502015-09-05 16:11:27 -04001828 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1829 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001830 """
1831 cert = X509()
1832 name = cert.get_issuer()
1833 name.C = 'AU'
1834 name.O = 'Unit Tests'
1835 cert.set_issuer(name)
1836 self.assertEquals(
1837 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001838 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001839
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001840 def test_get_pubkey_uninitialized(self):
1841 """
Alex Gaynor31287502015-09-05 16:11:27 -04001842 When called on a certificate with no public key,
1843 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001844 """
1845 cert = X509()
1846 self.assertRaises(Error, cert.get_pubkey)
1847
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001848 def test_subject_name_hash_wrong_args(self):
1849 """
Alex Gaynor31287502015-09-05 16:11:27 -04001850 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1851 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001852 """
1853 cert = X509()
1854 self.assertRaises(TypeError, cert.subject_name_hash, None)
1855
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001856 def test_subject_name_hash(self):
1857 """
Alex Gaynor31287502015-09-05 16:11:27 -04001858 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1859 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001860 """
1861 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001862 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001863 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001864 [3350047874, # OpenSSL 0.9.8, MD5
1865 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001866 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001867
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001868 def test_get_signature_algorithm(self):
1869 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001870 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001871 the algorithm used to sign the certificate.
1872 """
1873 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001874 self.assertEqual(
1875 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001876
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001877 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001878 """
Alex Gaynor31287502015-09-05 16:11:27 -04001879 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1880 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001881 """
1882 # This certificate has been modified to indicate a bogus OID in the
1883 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001884 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001885-----BEGIN CERTIFICATE-----
1886MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1887EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1888cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1889MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1890EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1891CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1892AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1893+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1894hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1895BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1896FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1897dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1898aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1899MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1900jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1901PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1902tgI5
1903-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001904""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001905 cert = load_certificate(FILETYPE_PEM, certPEM)
1906 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001907
1908
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001909class X509StoreTests(TestCase):
1910 """
1911 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1912 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001913
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001914 def test_type(self):
1915 """
1916 :py:obj:`X509StoreType` is a type object.
1917 """
1918 self.assertIdentical(X509Store, X509StoreType)
1919 self.assertConsistentType(X509Store, 'X509Store')
1920
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001921 def test_add_cert_wrong_args(self):
1922 store = X509Store()
1923 self.assertRaises(TypeError, store.add_cert)
1924 self.assertRaises(TypeError, store.add_cert, object())
1925 self.assertRaises(TypeError, store.add_cert, X509(), object())
1926
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001927 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001928 """
1929 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1930 certificate store.
1931 """
1932 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001933 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001934 store.add_cert(cert)
1935
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001936 def test_add_cert_rejects_duplicate(self):
1937 """
Alex Gaynor31287502015-09-05 16:11:27 -04001938 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1939 an attempt is made to add the same certificate to the store more than
1940 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001941 """
1942 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1943 store = X509Store()
1944 store.add_cert(cert)
1945 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001946
1947
Rick Dean623ee362009-07-17 12:22:16 -05001948class PKCS12Tests(TestCase):
1949 """
Alex Gaynor31287502015-09-05 16:11:27 -04001950 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1951 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001952 """
1953 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1954
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001955 def test_type(self):
1956 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001957 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001958 """
1959 self.assertIdentical(PKCS12, PKCS12Type)
1960 self.assertConsistentType(PKCS12, 'PKCS12')
1961
Rick Deanf94096c2009-07-18 14:23:06 -05001962 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001963 """
Alex Gaynor31287502015-09-05 16:11:27 -04001964 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1965 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001966 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001967 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001968 self.assertEqual(None, p12.get_certificate())
1969 self.assertEqual(None, p12.get_privatekey())
1970 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001971 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001972
1973 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001974 """
Alex Gaynor31287502015-09-05 16:11:27 -04001975 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1976 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1977 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1978 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001979 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001980 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001981 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001982 self.assertRaises(TypeError, p12.set_certificate, PKey())
1983 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001984 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001985 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1986 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001987 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1988 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1989 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001990 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001991 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1992 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001993
1994 def test_key_only(self):
1995 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001996 A :py:obj:`PKCS12` with only a private key can be exported using
1997 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001998 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001999 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002000 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002001 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002002 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05002003 self.assertEqual(None, p12.get_certificate())
2004 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002005 try:
2006 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2007 except Error:
2008 # Some versions of OpenSSL will throw an exception
2009 # for this nearly useless PKCS12 we tried to generate:
2010 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2011 return
Rick Dean623ee362009-07-17 12:22:16 -05002012 p12 = load_pkcs12(dumped_p12, passwd)
2013 self.assertEqual(None, p12.get_ca_certificates())
2014 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002015
2016 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2017 # future this will be improved.
2018 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05002019
2020 def test_cert_only(self):
2021 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002022 A :py:obj:`PKCS12` with only a certificate can be exported using
2023 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002024 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002025 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002026 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002027 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002028 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05002029 self.assertEqual(cert, p12.get_certificate())
2030 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002031 try:
2032 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2033 except Error:
2034 # Some versions of OpenSSL will throw an exception
2035 # for this nearly useless PKCS12 we tried to generate:
2036 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2037 return
Rick Dean623ee362009-07-17 12:22:16 -05002038 p12 = load_pkcs12(dumped_p12, passwd)
2039 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002040
2041 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
2042 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2043
2044 # Oh ho. It puts the certificate into the ca certificates list, in
2045 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2046 # that to check to see if it reconstructed the certificate we expected
2047 # it to. At some point, hopefully this will change so that
2048 # p12.get_certificate() is actually what returns the loaded
2049 # certificate.
2050 self.assertEqual(
2051 cleartextCertificatePEM,
2052 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002053
Alex Gaynor31287502015-09-05 16:11:27 -04002054 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2055 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002056 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002057 Generate a PKCS12 object with components from PEM. Verify that the set
2058 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002059 """
Rick Deanf94096c2009-07-18 14:23:06 -05002060 p12 = PKCS12()
2061 if cert_pem:
2062 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2063 self.assertEqual(ret, None)
2064 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002065 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002066 self.assertEqual(ret, None)
2067 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002068 ret = p12.set_ca_certificates(
2069 (load_certificate(FILETYPE_PEM, ca_pem),)
2070 )
Rick Deanf94096c2009-07-18 14:23:06 -05002071 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002072 if friendly_name:
2073 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002074 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002075 return p12
2076
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002077 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002078 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002079 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002080 Use openssl program to confirm three components are recoverable from a
2081 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002082 """
2083 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002084 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002085 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2086 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002087 self.assertEqual(recovered_key[-len(key):], key)
2088 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002089 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002090 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2091 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002092 self.assertEqual(recovered_cert[-len(cert):], cert)
2093 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002094 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002095 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2096 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002097 self.assertEqual(recovered_cert[-len(ca):], ca)
2098
Stephen Holsapple38482622014-04-05 20:29:34 -07002099 def verify_pkcs12_container(self, p12):
2100 """
2101 Verify that the PKCS#12 container contains the correct client
2102 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002103
2104 :param p12: The PKCS12 instance to verify.
2105 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002106 """
2107 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2108 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002109 self.assertEqual(
2110 (client_cert_pem, client_key_pem, None),
2111 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002112
Rick Deanf94096c2009-07-18 14:23:06 -05002113 def test_load_pkcs12(self):
2114 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002115 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002116 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002117 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002118 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002119 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002120 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002121 pem,
2122 b"pkcs12",
2123 b"-export",
2124 b"-clcerts",
2125 b"-passout",
2126 b"pass:" + passwd
2127 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002128 p12 = load_pkcs12(p12_str, passphrase=passwd)
2129 self.verify_pkcs12_container(p12)
2130
Abraham Martinc5484ba2015-03-25 15:33:05 +00002131 def test_load_pkcs12_text_passphrase(self):
2132 """
2133 A PKCS12 string generated using the openssl command line can be loaded
2134 with :py:obj:`load_pkcs12` and its components extracted and examined.
2135 Using text as passphrase instead of bytes. DeprecationWarning expected.
2136 """
2137 pem = client_key_pem + client_cert_pem
2138 passwd = b"whatever"
2139 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2140 b"-passout", b"pass:" + passwd)
2141 with catch_warnings(record=True) as w:
2142 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002143 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002144
2145 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002146 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002147 WARNING_TYPE_EXPECTED
2148 ),
2149 str(w[-1].message)
2150 )
2151 self.assertIs(w[-1].category, DeprecationWarning)
2152
Abraham Martinc5484ba2015-03-25 15:33:05 +00002153 self.verify_pkcs12_container(p12)
2154
Stephen Holsapple38482622014-04-05 20:29:34 -07002155 def test_load_pkcs12_no_passphrase(self):
2156 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002157 A PKCS12 string generated using openssl command line can be loaded with
2158 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2159 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002160 """
2161 pem = client_key_pem + client_cert_pem
2162 p12_str = _runopenssl(
2163 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2164 p12 = load_pkcs12(p12_str)
2165 self.verify_pkcs12_container(p12)
2166
Stephen Holsapple38482622014-04-05 20:29:34 -07002167 def _dump_and_load(self, dump_passphrase, load_passphrase):
2168 """
2169 A helper method to dump and load a PKCS12 object.
2170 """
2171 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2172 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2173 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2174
Stephen Holsapple38482622014-04-05 20:29:34 -07002175 def test_load_pkcs12_null_passphrase_load_empty(self):
2176 """
2177 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002178 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002179 extracted and examined.
2180 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002181 self.verify_pkcs12_container(
2182 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002183
Stephen Holsapple38482622014-04-05 20:29:34 -07002184 def test_load_pkcs12_null_passphrase_load_null(self):
2185 """
2186 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002187 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002188 extracted and examined.
2189 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002190 self.verify_pkcs12_container(
2191 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002192
Stephen Holsapple38482622014-04-05 20:29:34 -07002193 def test_load_pkcs12_empty_passphrase_load_empty(self):
2194 """
2195 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002196 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002197 extracted and examined.
2198 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002199 self.verify_pkcs12_container(
2200 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002201
Stephen Holsapple38482622014-04-05 20:29:34 -07002202 def test_load_pkcs12_empty_passphrase_load_null(self):
2203 """
2204 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002205 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002206 extracted and examined.
2207 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002208 self.verify_pkcs12_container(
2209 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002210
Rick Deanee568302009-07-24 09:56:29 -05002211 def test_load_pkcs12_garbage(self):
2212 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002213 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2214 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002215 """
2216 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002217 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002218 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2219 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002220
Rick Deanf94096c2009-07-18 14:23:06 -05002221 def test_replace(self):
2222 """
Alex Gaynor31287502015-09-05 16:11:27 -04002223 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2224 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002225 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002226 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002227 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2228 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2229 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002230 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002231 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002232 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002233 self.assertEqual(1, len(p12.get_ca_certificates()))
2234 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002235 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002236 self.assertEqual(2, len(p12.get_ca_certificates()))
2237 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2238 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2239
Rick Deanf94096c2009-07-18 14:23:06 -05002240 def test_friendly_name(self):
2241 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002242 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002243 :py:obj:`PKCS12.get_friendlyname` and
2244 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2245 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002246 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002247 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002248 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002249 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002250 p12.set_friendlyname(friendly_name)
2251 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002252 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002253 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002254 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002255 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002256 # We would use the openssl program to confirm the friendly
2257 # name, but it is not possible. The pkcs12 command
2258 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002259 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002260 self.check_recovery(
2261 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2262 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002263
Rick Deanf94096c2009-07-18 14:23:06 -05002264 def test_various_empty_passphrases(self):
2265 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002266 Test that missing, None, and '' passphrases are identical for PKCS12
2267 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002268 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002269 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002270 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002271 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2272 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2273 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2274 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2275 self.check_recovery(
2276 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2277 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002278
Rick Deanf94096c2009-07-18 14:23:06 -05002279 def test_removing_ca_cert(self):
2280 """
Alex Gaynor31287502015-09-05 16:11:27 -04002281 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2282 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002283 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002284 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2285 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002286 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002287
Rick Deanf94096c2009-07-18 14:23:06 -05002288 def test_export_without_mac(self):
2289 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002290 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002291 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002292 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002293 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002294 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002295 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002296 self.check_recovery(
2297 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002298 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002299
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002300 def test_load_without_mac(self):
2301 """
2302 Loading a PKCS12 without a MAC does something other than crash.
2303 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002304 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002305 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2306 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002307 try:
2308 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2309 # The person who generated this PCKS12 should be flogged,
2310 # or better yet we should have a means to determine
2311 # whether a PCKS12 had a MAC that was verified.
2312 # Anyway, libopenssl chooses to allow it, so the
2313 # pyopenssl binding does as well.
2314 self.assertTrue(isinstance(recovered_p12, PKCS12))
2315 except Error:
2316 # Failing here with an exception is preferred as some openssl
2317 # versions do.
2318 pass
Rick Dean623ee362009-07-17 12:22:16 -05002319
Rick Dean25bcc1f2009-07-20 11:53:13 -05002320 def test_zero_len_list_for_ca(self):
2321 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002322 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002323 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002324 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002325 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002326 p12.set_ca_certificates([])
2327 self.assertEqual((), p12.get_ca_certificates())
2328 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2329 self.check_recovery(
2330 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2331 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002332
Rick Deanf94096c2009-07-18 14:23:06 -05002333 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002334 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002335 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002336 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002337 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002338 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002339 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002340 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002341
Abraham Martinc5484ba2015-03-25 15:33:05 +00002342 def test_export_without_bytes(self):
2343 """
2344 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2345 """
2346 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2347
2348 with catch_warnings(record=True) as w:
2349 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002350 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002351 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002352 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002353 WARNING_TYPE_EXPECTED
2354 ),
2355 str(w[-1].message)
2356 )
2357 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002358 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002359 dumped_p12,
2360 key=server_key_pem,
2361 cert=server_cert_pem,
2362 passwd=b"randomtext"
2363 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002364
Rick Deanf94096c2009-07-18 14:23:06 -05002365 def test_key_cert_mismatch(self):
2366 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002367 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002368 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002369 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002370 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2371 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002372
2373
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002374# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002375_cmdLineQuoteRe = re.compile(br'(\\*)"')
2376_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002377
2378
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002379def cmdLineQuote(s):
2380 """
2381 Internal method for quoting a single command-line argument.
2382
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002383 See http://www.perlmonks.org/?node_id=764004
2384
Jonathan Ballet648875f2011-07-16 14:14:58 +09002385 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002386 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002387 cmd.exe-style quoting
2388
Jonathan Ballet648875f2011-07-16 14:14:58 +09002389 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002390 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002391 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002392 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2393 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002394
2395
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002396def quoteArguments(arguments):
2397 """
2398 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002399 a similar API. This allows the list passed to
2400 :py:obj:`reactor.spawnProcess` to match the child process's
2401 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002402
Jonathan Ballet648875f2011-07-16 14:14:58 +09002403 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002404 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002405
Jonathan Ballet648875f2011-07-16 14:14:58 +09002406 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002407 :return: A space-delimited string containing quoted versions of
2408 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002409 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002410 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002411
2412
Rick Dean4c9ad612009-07-17 15:05:22 -05002413def _runopenssl(pem, *args):
2414 """
2415 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002416 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002417 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002418 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002419 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002420 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2421 for arg in args
2422 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002423 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002424 command = b"openssl " + quoteArguments(args)
2425 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002426 proc.stdin.write(pem)
2427 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002428 output = proc.stdout.read()
2429 proc.stdout.close()
2430 proc.wait()
2431 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002432
2433
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002434class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002435 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002436 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002437 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002438 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002439 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002440 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002441 """
2442 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002443
2444 assert True is key._only_public
2445 assert 2048 == key.bits()
2446 assert TYPE_RSA == key.type()
2447
2448 def test_invalid_type(self):
2449 """
2450 load_publickey doesn't support FILETYPE_TEXT.
2451 """
2452 with pytest.raises(ValueError):
2453 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2454
2455 def test_invalid_key_format(self):
2456 """
2457 load_publickey explodes on incorrect keys.
2458 """
2459 with pytest.raises(Error):
2460 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2461
2462 def test_tolerates_unicode_strings(self):
2463 """
2464 load_publickey works with text strings, not just bytes.
2465 """
2466 serialized = cleartextPublicKeyPEM.decode('ascii')
2467 key = load_publickey(FILETYPE_PEM, serialized)
2468 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2469
2470 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002471
2472
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002473class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002474 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002475 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002476
2477 Add new tests to `TestFunctions` above.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002478 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002479
2480 def test_load_privatekey_invalid_format(self):
2481 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002482 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2483 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002484 """
2485 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2486
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002487 def test_load_privatekey_invalid_passphrase_type(self):
2488 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002489 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2490 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002491 """
2492 self.assertRaises(
2493 TypeError,
2494 load_privatekey,
2495 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2496
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002497 def test_load_privatekey_wrong_args(self):
2498 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002499 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2500 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002501 """
2502 self.assertRaises(TypeError, load_privatekey)
2503
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002504 def test_load_privatekey_wrongPassphrase(self):
2505 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002506 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2507 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002508 """
2509 self.assertRaises(
2510 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002511 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002512
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002513 def test_load_privatekey_passphraseWrongType(self):
2514 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002515 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2516 a passphrase with a private key encoded in a format, that doesn't
2517 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002518 """
2519 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2520 blob = dump_privatekey(FILETYPE_ASN1, key)
2521 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002522 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002523
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002524 def test_load_privatekey_passphrase(self):
2525 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002526 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2527 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002528 """
2529 key = load_privatekey(
2530 FILETYPE_PEM, encryptedPrivateKeyPEM,
2531 encryptedPrivateKeyPEMPassphrase)
2532 self.assertTrue(isinstance(key, PKeyType))
2533
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002534 def test_load_privatekey_passphrase_exception(self):
2535 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002536 If the passphrase callback raises an exception, that exception is
2537 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002538 """
2539 def cb(ignored):
2540 raise ArithmeticError
2541
Alex Gaynor791212d2015-09-05 15:46:08 -04002542 with pytest.raises(ArithmeticError):
2543 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002544
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002545 def test_load_privatekey_wrongPassphraseCallback(self):
2546 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002547 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2548 is passed an encrypted PEM and a passphrase callback which returns an
2549 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002550 """
2551 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002552
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002553 def cb(*a):
2554 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002555 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002556 self.assertRaises(
2557 Error,
2558 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2559 self.assertTrue(called)
2560
2561 def test_load_privatekey_passphraseCallback(self):
2562 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002563 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2564 encrypted PEM string if given a passphrase callback which returns the
2565 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002566 """
2567 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002568
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002569 def cb(writing):
2570 called.append(writing)
2571 return encryptedPrivateKeyPEMPassphrase
2572 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2573 self.assertTrue(isinstance(key, PKeyType))
2574 self.assertEqual(called, [False])
2575
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002576 def test_load_privatekey_passphrase_wrong_return_type(self):
2577 """
2578 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2579 callback returns something other than a byte string.
2580 """
2581 self.assertRaises(
2582 ValueError,
2583 load_privatekey,
2584 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2585
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002586 def test_dump_privatekey_wrong_args(self):
2587 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002588 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2589 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002590 """
2591 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002592 # If cipher name is given, password is required.
2593 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002594 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002595
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002596 def test_dump_privatekey_unknown_cipher(self):
2597 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002598 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2599 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002600 """
2601 key = PKey()
2602 key.generate_key(TYPE_RSA, 512)
2603 self.assertRaises(
2604 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002605 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002606
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002607 def test_dump_privatekey_invalid_passphrase_type(self):
2608 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002609 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2610 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002611 """
2612 key = PKey()
2613 key.generate_key(TYPE_RSA, 512)
2614 self.assertRaises(
2615 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002616 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002617
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002618 def test_dump_privatekey_invalid_filetype(self):
2619 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002620 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2621 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002622 """
2623 key = PKey()
2624 key.generate_key(TYPE_RSA, 512)
2625 self.assertRaises(ValueError, dump_privatekey, 100, key)
2626
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002627 def test_load_privatekey_passphraseCallbackLength(self):
2628 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002629 :py:obj:`crypto.load_privatekey` should raise an error when the
2630 passphrase provided by the callback is too long, not silently truncate
2631 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002632 """
2633 def cb(ignored):
2634 return "a" * 1025
2635
Alex Gaynor791212d2015-09-05 15:46:08 -04002636 with pytest.raises(ValueError):
2637 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002638
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002639 def test_dump_privatekey_passphrase(self):
2640 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002641 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2642 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002643 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002644 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002645 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002646 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2647 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002648 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2649 self.assertTrue(isinstance(loadedKey, PKeyType))
2650 self.assertEqual(loadedKey.type(), key.type())
2651 self.assertEqual(loadedKey.bits(), key.bits())
2652
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002653 def test_dump_privatekey_passphraseWrongType(self):
2654 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002655 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2656 a passphrase with a private key encoded in a format, that doesn't
2657 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002658 """
2659 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002660 with pytest.raises(ValueError):
2661 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002662
Rick Dean5b7b6372009-04-01 11:34:06 -05002663 def test_dump_certificate(self):
2664 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002665 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002666 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002667 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002668 cert = load_certificate(FILETYPE_PEM, pemData)
2669 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2670 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2671 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002672 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002673 self.assertEqual(dumped_der, good_der)
2674 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2675 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2676 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2677 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002678 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002679 self.assertEqual(dumped_text, good_text)
2680
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002681 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002682 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002683 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002684 """
2685 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002686 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002687 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2688 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002689
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002690 def test_dump_privatekey_asn1(self):
2691 """
2692 :py:obj:`dump_privatekey` writes a DER
2693 """
2694 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2695 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2696
Rick Dean5b7b6372009-04-01 11:34:06 -05002697 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002698 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002699 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002700 self.assertEqual(dumped_der, good_der)
2701 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2702 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2703 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002704
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002705 def test_dump_privatekey_text(self):
2706 """
2707 :py:obj:`dump_privatekey` writes a text
2708 """
2709 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2710 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2711
Rick Dean5b7b6372009-04-01 11:34:06 -05002712 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002713 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002714 self.assertEqual(dumped_text, good_text)
2715
Cory Benfield6492f7c2015-10-27 16:57:58 +09002716 def test_dump_publickey_pem(self):
2717 """
Cory Benfield11c10192015-10-27 17:23:03 +09002718 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002719 """
2720 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2721 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002722 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002723
2724 def test_dump_publickey_asn1(self):
2725 """
Cory Benfield11c10192015-10-27 17:23:03 +09002726 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002727 """
2728 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2729 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2730 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2731 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002732 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002733
Cory Benfielde02c7d82015-10-27 17:34:49 +09002734 def test_dump_publickey_invalid_type(self):
2735 """
2736 dump_publickey doesn't support FILETYPE_TEXT.
2737 """
2738 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2739
2740 with pytest.raises(ValueError):
2741 dump_publickey(FILETYPE_TEXT, key)
2742
Rick Dean5b7b6372009-04-01 11:34:06 -05002743 def test_dump_certificate_request(self):
2744 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002745 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002746 """
Alex Gaynor31287502015-09-05 16:11:27 -04002747 req = load_certificate_request(
2748 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002749 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2750 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2751 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002752 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002753 self.assertEqual(dumped_der, good_der)
2754 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2755 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2756 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2757 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002758 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002759 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002760 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002761
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002762 def test_dump_privatekey_passphraseCallback(self):
2763 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002764 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2765 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002766 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002767 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002768 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002769
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002770 def cb(writing):
2771 called.append(writing)
2772 return passphrase
2773 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002774 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2775 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002776 self.assertEqual(called, [True])
2777 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2778 self.assertTrue(isinstance(loadedKey, PKeyType))
2779 self.assertEqual(loadedKey.type(), key.type())
2780 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002781
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002782 def test_dump_privatekey_passphrase_exception(self):
2783 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002784 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002785 by the passphrase callback.
2786 """
2787 def cb(ignored):
2788 raise ArithmeticError
2789
2790 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002791 with pytest.raises(ArithmeticError):
2792 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002793
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002794 def test_dump_privatekey_passphraseCallbackLength(self):
2795 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002796 :py:obj:`crypto.dump_privatekey` should raise an error when the
2797 passphrase provided by the callback is too long, not silently truncate
2798 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002799 """
2800 def cb(ignored):
2801 return "a" * 1025
2802
2803 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002804 with pytest.raises(ValueError):
2805 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002806
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002807 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002808 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002809 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2810 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002811 """
2812 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2813 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2814
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002815 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002816 """
2817 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2818 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2819 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002820 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2821 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2822
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002823 def test_load_pkcs7_data_invalid(self):
2824 """
2825 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2826 :py:obj:`Error` is raised.
2827 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002828 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002829
Alex Gaynor09a386e2016-07-03 09:32:44 -04002830 def test_load_pkcs7_type_invalid(self):
2831 """
2832 If the type passed to :obj:`load_pkcs7_data`, :obj:`ValueError` is
2833 raised.
2834 """
2835 with pytest.raises(ValueError):
2836 load_pkcs7_data(object(), b"foo")
2837
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002838
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002839class LoadCertificateTests(TestCase):
2840 """
2841 Tests for :py:obj:`load_certificate_request`.
2842 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002843
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002844 def test_badFileType(self):
2845 """
2846 If the file type passed to :py:obj:`load_certificate_request` is
2847 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2848 :py:class:`ValueError` is raised.
2849 """
2850 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2851
2852
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002853class PKCS7Tests(TestCase):
2854 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002855 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002856 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002857
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002858 def test_type(self):
2859 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002860 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002861 """
2862 self.assertTrue(isinstance(PKCS7Type, type))
2863 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2864
2865 # XXX This doesn't currently work.
2866 # self.assertIdentical(PKCS7, PKCS7Type)
2867
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002868 # XXX Opposite results for all these following methods
2869
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002870 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002871 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002872 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2873 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002874 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002875 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2876 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2877
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002878 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002879 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002880 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2881 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002882 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002883 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2884 self.assertTrue(pkcs7.type_is_signed())
2885
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002886 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002887 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002888 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2889 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002890 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002891 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2892 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2893
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002894 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002895 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002896 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2897 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002898 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002899 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2900 self.assertFalse(pkcs7.type_is_enveloped())
2901
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002902 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002903 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002904 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2905 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002906 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002907 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2908 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2909
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002910 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002911 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002912 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2913 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002914 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002915 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2916 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2917
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002918 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002919 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002920 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2921 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002922 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002923 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2924 self.assertFalse(pkcs7.type_is_data())
2925
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002926 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002927 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002928 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2929 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002930 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002931 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2932 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2933
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002934 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002935 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002936 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2937 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002938 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002939 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2940 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2941
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002942 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002943 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002944 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2945 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002946 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002947 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002948 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002949
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002950 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002951 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002952 If an attribute other than one of the methods tested here is accessed
2953 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2954 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002955 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002956 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2957 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2958
2959
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002960class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002961 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002962 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002963 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002964
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002965 def signable(self):
2966 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002967 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002968 """
2969 return NetscapeSPKI()
2970
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002971 def test_type(self):
2972 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002973 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2974 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002975 """
2976 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2977 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2978
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002979 def test_construction(self):
2980 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002981 :py:obj:`NetscapeSPKI` returns an instance of
2982 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002983 """
2984 nspki = NetscapeSPKI()
2985 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2986
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002987 def test_invalid_attribute(self):
2988 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002989 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2990 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002991 """
2992 nspki = NetscapeSPKI()
2993 self.assertRaises(AttributeError, lambda: nspki.foo)
2994
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002995 def test_b64_encode(self):
2996 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002997 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2998 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002999 """
3000 nspki = NetscapeSPKI()
3001 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003002 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003003
3004
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003005class TestRevoked(object):
3006 """
3007 Please add test cases for the Revoked class here if possible. This class
3008 holds the new py.test style tests.
3009 """
3010 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3011 """
3012 The get_reason method on the Revoked class checks to see if the
3013 extension is NID_crl_reason and should skip it otherwise. This test
3014 loads a CRL with extensions it should ignore.
3015 """
3016 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3017 revoked = crl.get_revoked()
3018 reason = revoked[1].get_reason()
3019 assert reason == b'Unspecified'
3020
3021 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3022 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3023 revoked = crl.get_revoked()
3024 revoked[1].set_reason(None)
3025 reason = revoked[1].get_reason()
3026 assert reason is None
3027
3028
Rick Dean536ba022009-07-24 23:57:27 -05003029class RevokedTests(TestCase):
3030 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003031 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3032 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003033 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003034
Rick Dean536ba022009-07-24 23:57:27 -05003035 def test_construction(self):
3036 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003037 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003038 that it is empty.
3039 """
3040 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003041 self.assertTrue(isinstance(revoked, Revoked))
3042 self.assertEquals(type(revoked), Revoked)
3043 self.assertEquals(revoked.get_serial(), b('00'))
3044 self.assertEquals(revoked.get_rev_date(), None)
3045 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003046
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003047 def test_construction_wrong_args(self):
3048 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003049 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3050 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003051 """
3052 self.assertRaises(TypeError, Revoked, None)
3053 self.assertRaises(TypeError, Revoked, 1)
3054 self.assertRaises(TypeError, Revoked, "foo")
3055
Rick Dean536ba022009-07-24 23:57:27 -05003056 def test_serial(self):
3057 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003058 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003059 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003060 with grace.
3061 """
3062 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003063 ret = revoked.set_serial(b('10b'))
3064 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003065 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003066 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003067
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003068 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003069 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003070 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003071
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003072 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003073 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003074 self.assertRaises(TypeError, revoked.get_serial, 1)
3075 self.assertRaises(TypeError, revoked.get_serial, None)
3076 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003077
Rick Dean536ba022009-07-24 23:57:27 -05003078 def test_date(self):
3079 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003080 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003081 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003082 with grace.
3083 """
3084 revoked = Revoked()
3085 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003086 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003087
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003088 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003089 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003090 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003091 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003092 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003093
Rick Dean6385faf2009-07-26 00:07:47 -05003094 def test_reason(self):
3095 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003096 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003097 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003098 as "set". Likewise, each reason of all_reasons() must work.
3099 """
3100 revoked = Revoked()
3101 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003102 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003103 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003104 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003105 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003106 self.assertEquals(
3107 reason.lower().replace(b(' '), b('')),
3108 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003109 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003110
3111 revoked.set_reason(None)
3112 self.assertEqual(revoked.get_reason(), None)
3113
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003114 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003115 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003116 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003117 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003118 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003119 """
3120 revoked = Revoked()
3121 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003122 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003123
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003124 def test_get_reason_wrong_arguments(self):
3125 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003126 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3127 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003128 """
3129 revoked = Revoked()
3130 self.assertRaises(TypeError, revoked.get_reason, None)
3131 self.assertRaises(TypeError, revoked.get_reason, 1)
3132 self.assertRaises(TypeError, revoked.get_reason, "foo")
3133
3134
Rick Dean536ba022009-07-24 23:57:27 -05003135class CRLTests(TestCase):
3136 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003137 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003138 """
3139 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3140 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3141
Dan Sully44e767a2016-06-04 18:05:27 -07003142 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3143 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3144 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3145 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3146 intermediate_server_cert = load_certificate(
3147 FILETYPE_PEM, intermediate_server_cert_pem)
3148 intermediate_server_key = load_privatekey(
3149 FILETYPE_PEM, intermediate_server_key_pem)
3150
Rick Dean536ba022009-07-24 23:57:27 -05003151 def test_construction(self):
3152 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003153 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003154 that it is empty
3155 """
3156 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003157 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003158 self.assertEqual(crl.get_revoked(), None)
3159
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003160 def test_construction_wrong_args(self):
3161 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003162 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3163 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003164 """
3165 self.assertRaises(TypeError, CRL, 1)
3166 self.assertRaises(TypeError, CRL, "")
3167 self.assertRaises(TypeError, CRL, None)
3168
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003169 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003170 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003171 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003172 """
3173 crl = CRL()
3174 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003175 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003176 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003177 revoked.set_serial(b('3ab'))
3178 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003179 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003180 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003181
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003182 def test_export_pem(self):
3183 """
3184 If not passed a format, ``CRL.export`` returns a "PEM" format string
3185 representing a serial number, a revoked reason, and certificate issuer
3186 information.
3187 """
3188 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003189 # PEM format
3190 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003191 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003192
3193 # These magic values are based on the way the CRL above was constructed
3194 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003195 text.index(b('Serial Number: 03AB'))
3196 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003197 text.index(
3198 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3199 )
3200
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003201 def test_export_der(self):
3202 """
3203 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3204 "DER" format string representing a serial number, a revoked reason, and
3205 certificate issuer information.
3206 """
3207 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003208
3209 # DER format
3210 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003211 text = _runopenssl(
3212 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3213 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003214 text.index(b('Serial Number: 03AB'))
3215 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003216 text.index(
3217 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3218 )
3219
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003220 def test_export_text(self):
3221 """
3222 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3223 text format string like the one produced by the openssl command line
3224 tool.
3225 """
3226 crl = self._get_crl()
3227
3228 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3229 text = _runopenssl(
3230 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3231 )
Rick Dean536ba022009-07-24 23:57:27 -05003232
3233 # text format
3234 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3235 self.assertEqual(text, dumped_text)
3236
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003237 def test_export_custom_digest(self):
3238 """
3239 If passed the name of a digest function, ``CRL.export`` uses a
3240 signature algorithm based on that digest function.
3241 """
3242 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003243 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003244 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3245 text.index(b('Signature Algorithm: sha1'))
3246
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003247 def test_export_md5_digest(self):
3248 """
3249 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3250 not emit a deprecation warning.
3251 """
3252 crl = self._get_crl()
3253 with catch_warnings(record=True) as catcher:
3254 simplefilter("always")
3255 self.assertEqual(0, len(catcher))
3256 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3257 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3258 text.index(b('Signature Algorithm: md5'))
3259
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003260 def test_export_default_digest(self):
3261 """
3262 If not passed the name of a digest function, ``CRL.export`` uses a
3263 signature algorithm based on MD5 and emits a deprecation warning.
3264 """
3265 crl = self._get_crl()
3266 with catch_warnings(record=True) as catcher:
3267 simplefilter("always")
3268 dumped_crl = crl.export(self.cert, self.pkey)
3269 self.assertEqual(
3270 "The default message digest (md5) is deprecated. "
3271 "Pass the name of a message digest explicitly.",
3272 str(catcher[0].message),
3273 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003274 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3275 text.index(b('Signature Algorithm: md5'))
3276
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003277 def test_export_invalid(self):
3278 """
3279 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003280 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003281 """
3282 crl = CRL()
3283 self.assertRaises(Error, crl.export, X509(), PKey())
3284
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003285 def test_add_revoked_keyword(self):
3286 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003287 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003288 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003289 """
3290 crl = CRL()
3291 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003292 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003293 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003294 crl.add_revoked(revoked=revoked)
3295 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3296
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003297 def test_export_wrong_args(self):
3298 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003299 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003300 four arguments, or with arguments other than the certificate,
3301 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003302 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003303 """
3304 crl = CRL()
3305 self.assertRaises(TypeError, crl.export)
3306 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003307 with pytest.raises(TypeError):
3308 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3309 with pytest.raises(TypeError):
3310 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3311 with pytest.raises(TypeError):
3312 crl.export(self.cert, None, FILETYPE_PEM, 10)
3313 with pytest.raises(TypeError):
3314 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003315 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3316
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003317 def test_export_unknown_filetype(self):
3318 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003319 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003320 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3321 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003322 """
3323 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003324 with pytest.raises(ValueError):
3325 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003326
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003327 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003328 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003329 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003330 in a :py:obj:`ValueError` being raised.
3331 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003332 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003333 self.assertRaises(
3334 ValueError,
3335 crl.export,
3336 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3337 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003338
Rick Dean536ba022009-07-24 23:57:27 -05003339 def test_get_revoked(self):
3340 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003341 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003342 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3343 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003344 """
3345 crl = CRL()
3346
3347 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003348 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003349 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003350 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003351 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003352 revoked.set_serial(b('100'))
3353 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003354 crl.add_revoked(revoked)
3355
3356 revs = crl.get_revoked()
3357 self.assertEqual(len(revs), 2)
3358 self.assertEqual(type(revs[0]), Revoked)
3359 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003360 self.assertEqual(revs[0].get_serial(), b('03AB'))
3361 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003362 self.assertEqual(revs[0].get_rev_date(), now)
3363 self.assertEqual(revs[1].get_rev_date(), now)
3364
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003365 def test_get_revoked_wrong_args(self):
3366 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003367 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3368 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003369 """
3370 crl = CRL()
3371 self.assertRaises(TypeError, crl.get_revoked, None)
3372 self.assertRaises(TypeError, crl.get_revoked, 1)
3373 self.assertRaises(TypeError, crl.get_revoked, "")
3374 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3375
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003376 def test_add_revoked_wrong_args(self):
3377 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003378 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3379 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003380 """
3381 crl = CRL()
3382 self.assertRaises(TypeError, crl.add_revoked)
3383 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3384 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3385
Rick Dean536ba022009-07-24 23:57:27 -05003386 def test_load_crl(self):
3387 """
3388 Load a known CRL and inspect its revocations. Both
3389 PEM and DER formats are loaded.
3390 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003391 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003392 revs = crl.get_revoked()
3393 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003394 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003395 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003396 self.assertEqual(revs[1].get_serial(), b('0100'))
3397 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003398
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003399 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003400 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003401 revs = crl.get_revoked()
3402 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003403 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003404 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003405 self.assertEqual(revs[1].get_serial(), b('0100'))
3406 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003407
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003408 def test_load_crl_wrong_args(self):
3409 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003410 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3411 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003412 """
3413 self.assertRaises(TypeError, load_crl)
3414 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3415 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3416
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003417 def test_load_crl_bad_filetype(self):
3418 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003419 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3420 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003421 """
3422 self.assertRaises(ValueError, load_crl, 100, crlData)
3423
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003424 def test_load_crl_bad_data(self):
3425 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003426 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3427 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003428 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003429 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003430
Dan Sully44e767a2016-06-04 18:05:27 -07003431 def test_get_issuer(self):
3432 """
3433 Load a known CRL and assert its issuer's common name is
3434 what we expect from the encoded crlData string.
3435 """
3436 crl = load_crl(FILETYPE_PEM, crlData)
3437 self.assertTrue(isinstance(crl.get_issuer(), X509Name))
3438 self.assertEqual(crl.get_issuer().CN, 'Testing Root CA')
3439
Dominic Chenf05b2122015-10-13 16:32:35 +00003440 def test_dump_crl(self):
3441 """
3442 The dumped CRL matches the original input.
3443 """
3444 crl = load_crl(FILETYPE_PEM, crlData)
3445 buf = dump_crl(FILETYPE_PEM, crl)
3446 assert buf == crlData
3447
Dan Sully44e767a2016-06-04 18:05:27 -07003448 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3449 """
3450 Create a CRL.
3451
3452 :param list[X509] certs: A list of certificates to revoke.
3453 :rtype: CRL
3454 """
3455 crl = CRL()
3456 for cert in certs:
3457 revoked = Revoked()
3458 # FIXME: This string splicing is an unfortunate implementation
3459 # detail that has been reported in
3460 # https://github.com/pyca/pyopenssl/issues/258
3461 serial = hex(cert.get_serial_number())[2:].encode('utf-8')
3462 revoked.set_serial(serial)
3463 revoked.set_reason(b'unspecified')
3464 revoked.set_rev_date(b'20140601000000Z')
3465 crl.add_revoked(revoked)
3466 crl.set_version(1)
3467 crl.set_lastUpdate(b'20140601000000Z')
3468 crl.set_nextUpdate(b'20180601000000Z')
3469 crl.sign(issuer_cert, issuer_key, digest=b'sha512')
3470 return crl
3471
3472 def test_verify_with_revoked(self):
3473 """
3474 :func:`verify_certificate` raises error when an intermediate
3475 certificate is revoked.
3476 """
3477 store = X509Store()
3478 store.add_cert(self.root_cert)
3479 store.add_cert(self.intermediate_cert)
3480 root_crl = self._make_test_crl(
3481 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3482 intermediate_crl = self._make_test_crl(
3483 self.intermediate_cert, self.intermediate_key, certs=[])
3484 store.add_crl(root_crl)
3485 store.add_crl(intermediate_crl)
3486 store.set_flags(
3487 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3488 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3489 e = self.assertRaises(
3490 X509StoreContextError, store_ctx.verify_certificate)
3491 self.assertEqual(e.args[0][2], 'certificate revoked')
3492
3493 def test_verify_with_missing_crl(self):
3494 """
3495 :func:`verify_certificate` raises error when an intermediate
3496 certificate's CRL is missing.
3497 """
3498 store = X509Store()
3499 store.add_cert(self.root_cert)
3500 store.add_cert(self.intermediate_cert)
3501 root_crl = self._make_test_crl(
3502 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3503 store.add_crl(root_crl)
3504 store.set_flags(
3505 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3506 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3507 e = self.assertRaises(
3508 X509StoreContextError, store_ctx.verify_certificate)
3509 self.assertEqual(e.args[0][2], 'unable to get certificate CRL')
3510 self.assertEqual(
3511 e.certificate.get_subject().CN, 'intermediate-service')
3512
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003513
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003514class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003515 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003516 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003517 """
3518 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3519 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003520 intermediate_server_cert = load_certificate(
3521 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003522
3523 def test_valid(self):
3524 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003525 :py:obj:`verify_certificate` returns ``None`` when called with a
3526 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003527 """
3528 store = X509Store()
3529 store.add_cert(self.root_cert)
3530 store.add_cert(self.intermediate_cert)
3531 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003532 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003533
3534 def test_reuse(self):
3535 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003536 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003537 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003538 """
3539 store = X509Store()
3540 store.add_cert(self.root_cert)
3541 store.add_cert(self.intermediate_cert)
3542 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003543 self.assertEqual(store_ctx.verify_certificate(), None)
3544 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003545
3546 def test_trusted_self_signed(self):
3547 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003548 :py:obj:`verify_certificate` returns ``None`` when called with a
3549 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003550 """
3551 store = X509Store()
3552 store.add_cert(self.root_cert)
3553 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003554 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003555
3556 def test_untrusted_self_signed(self):
3557 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003558 :py:obj:`verify_certificate` raises error when a self-signed
3559 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003560 """
3561 store = X509Store()
3562 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003563 with pytest.raises(X509StoreContextError) as exc:
3564 store_ctx.verify_certificate()
3565
3566 assert exc.value.args[0][2] == 'self signed certificate'
3567 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003568
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003569 def test_invalid_chain_no_root(self):
3570 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003571 :py:obj:`verify_certificate` raises error when a root certificate is
3572 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003573 """
3574 store = X509Store()
3575 store.add_cert(self.intermediate_cert)
3576 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003577
3578 with pytest.raises(X509StoreContextError) as exc:
3579 store_ctx.verify_certificate()
3580
3581 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3582 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003583
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003584 def test_invalid_chain_no_intermediate(self):
3585 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003586 :py:obj:`verify_certificate` raises error when an intermediate
3587 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003588 """
3589 store = X509Store()
3590 store.add_cert(self.root_cert)
3591 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003592
Alex Gaynor85b49702015-09-05 16:30:59 -04003593 with pytest.raises(X509StoreContextError) as exc:
3594 store_ctx.verify_certificate()
3595
3596 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3597 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003598
Stephen Holsapple46a09252015-02-12 14:45:43 -08003599 def test_modification_pre_verify(self):
3600 """
3601 :py:obj:`verify_certificate` can use a store context modified after
3602 instantiation.
3603 """
3604 store_bad = X509Store()
3605 store_bad.add_cert(self.intermediate_cert)
3606 store_good = X509Store()
3607 store_good.add_cert(self.root_cert)
3608 store_good.add_cert(self.intermediate_cert)
3609 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003610
3611 with pytest.raises(X509StoreContextError) as exc:
3612 store_ctx.verify_certificate()
3613
3614 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3615 assert exc.value.certificate.get_subject().CN == 'intermediate'
3616
Stephen Holsapple46a09252015-02-12 14:45:43 -08003617 store_ctx.set_store(store_good)
3618 self.assertEqual(store_ctx.verify_certificate(), None)
3619
3620
James Yonan7c2e5d32010-02-27 05:45:50 -07003621class SignVerifyTests(TestCase):
3622 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003623 Tests for :py:obj:`OpenSSL.crypto.sign` and
3624 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003625 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003626
James Yonan7c2e5d32010-02-27 05:45:50 -07003627 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003628 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003629 :py:obj:`sign` generates a cryptographic signature which
3630 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003631 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003632 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003633 "It was a bright cold day in April, and the clocks were striking "
3634 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3635 "effort to escape the vile wind, slipped quickly through the "
3636 "glass doors of Victory Mansions, though not quickly enough to "
3637 "prevent a swirl of gritty dust from entering along with him.")
3638
3639 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003640 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003641 # verify the content with this cert
3642 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3643 # certificate unrelated to priv_key, used to trigger an error
3644 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003645
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003646 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003647 sig = sign(priv_key, content, digest)
3648
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003649 # Verify the signature of content, will throw an exception if
3650 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003651 verify(good_cert, sig, content, digest)
3652
3653 # This should fail because the certificate doesn't match the
3654 # private key that was used to sign the content.
3655 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3656
3657 # This should fail because we've "tainted" the content after
3658 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003659 self.assertRaises(
3660 Error, verify,
3661 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003662
3663 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003664 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003665 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003666 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003667 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003668
Abraham Martinc5484ba2015-03-25 15:33:05 +00003669 def test_sign_verify_with_text(self):
3670 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003671 :py:obj:`sign` generates a cryptographic signature which
3672 :py:obj:`verify` can check. Deprecation warnings raised because using
3673 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003674 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003675 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003676 b"It was a bright cold day in April, and the clocks were striking "
3677 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3678 b"effort to escape the vile wind, slipped quickly through the "
3679 b"glass doors of Victory Mansions, though not quickly enough to "
3680 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003681 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003682
3683 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3684 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3685 for digest in ['md5', 'sha1']:
3686 with catch_warnings(record=True) as w:
3687 simplefilter("always")
3688 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003689
3690 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003691 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003692 WARNING_TYPE_EXPECTED
3693 ),
3694 str(w[-1].message)
3695 )
3696 self.assertIs(w[-1].category, DeprecationWarning)
3697
Abraham Martinc5484ba2015-03-25 15:33:05 +00003698 with catch_warnings(record=True) as w:
3699 simplefilter("always")
3700 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003701
3702 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003703 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003704 WARNING_TYPE_EXPECTED
3705 ),
3706 str(w[-1].message)
3707 )
3708 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003709
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003710 def test_sign_nulls(self):
3711 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003712 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003713 """
3714 content = b("Watch out! \0 Did you see it?")
3715 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3716 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3717 sig = sign(priv_key, content, "sha1")
3718 verify(good_cert, sig, content, "sha1")
3719
Colleen Murphye09399b2016-03-01 17:40:49 -08003720 def test_sign_with_large_key(self):
3721 """
3722 :py:obj:`sign` produces a signature for a string when using a long key.
3723 """
3724 content = b(
3725 "It was a bright cold day in April, and the clocks were striking "
3726 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3727 "effort to escape the vile wind, slipped quickly through the "
3728 "glass doors of Victory Mansions, though not quickly enough to "
3729 "prevent a swirl of gritty dust from entering along with him.")
3730
3731 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3732 sign(priv_key, content, "sha1")
3733
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003734
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003735class EllipticCurveTests(TestCase):
3736 """
3737 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3738 :py:obj:`get_elliptic_curves`.
3739 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003740
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003741 def test_set(self):
3742 """
3743 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3744 """
3745 self.assertIsInstance(get_elliptic_curves(), set)
3746
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003747 def test_some_curves(self):
3748 """
3749 If :py:mod:`cryptography` has elliptic curve support then the set
3750 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3751 it.
3752
3753 There could be an OpenSSL that violates this assumption. If so, this
3754 test will fail and we'll find out.
3755 """
3756 curves = get_elliptic_curves()
3757 if lib.Cryptography_HAS_EC:
3758 self.assertTrue(curves)
3759 else:
3760 self.assertFalse(curves)
3761
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003762 def test_a_curve(self):
3763 """
3764 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3765 supported curve.
3766 """
3767 curves = get_elliptic_curves()
3768 if curves:
3769 curve = next(iter(curves))
3770 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3771 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003772 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003773
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003774 def test_not_a_curve(self):
3775 """
3776 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3777 with a name which does not identify a supported curve.
3778 """
3779 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003780 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003781
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003782 def test_repr(self):
3783 """
3784 The string representation of a curve object includes simply states the
3785 object is a curve and what its name is.
3786 """
3787 curves = get_elliptic_curves()
3788 if curves:
3789 curve = next(iter(curves))
3790 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3791
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003792 def test_to_EC_KEY(self):
3793 """
3794 The curve object can export a version of itself as an EC_KEY* via the
3795 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3796 """
3797 curves = get_elliptic_curves()
3798 if curves:
3799 curve = next(iter(curves))
3800 # It's not easy to assert anything about this object. However, see
3801 # leakcheck/crypto.py for a test that demonstrates it at least does
3802 # not leak memory.
3803 curve._to_EC_KEY()
3804
3805
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003806class EllipticCurveFactory(object):
3807 """
3808 A helper to get the names of two curves.
3809 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003810
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003811 def __init__(self):
3812 curves = iter(get_elliptic_curves())
3813 try:
3814 self.curve_name = next(curves).name
3815 self.another_curve_name = next(curves).name
3816 except StopIteration:
3817 self.curve_name = self.another_curve_name = None
3818
3819
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003820class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3821 """
3822 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3823 """
3824 curve_factory = EllipticCurveFactory()
3825
3826 if curve_factory.curve_name is None:
3827 skip = "There are no curves available there can be no curve objects."
3828
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003829 def anInstance(self):
3830 """
3831 Get the curve object for an arbitrary curve supported by the system.
3832 """
3833 return get_elliptic_curve(self.curve_factory.curve_name)
3834
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003835 def anotherInstance(self):
3836 """
3837 Get the curve object for an arbitrary curve supported by the system -
3838 but not the one returned by C{anInstance}.
3839 """
3840 return get_elliptic_curve(self.curve_factory.another_curve_name)
3841
3842
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003843class EllipticCurveHashTests(TestCase):
3844 """
3845 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3846 as an item in a :py:type:`dict` or :py:type:`set`).
3847 """
3848 curve_factory = EllipticCurveFactory()
3849
3850 if curve_factory.curve_name is None:
3851 skip = "There are no curves available there can be no curve objects."
3852
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003853 def test_contains(self):
3854 """
3855 The ``in`` operator reports that a :py:type:`set` containing a curve
3856 does contain that curve.
3857 """
3858 curve = get_elliptic_curve(self.curve_factory.curve_name)
3859 curves = set([curve])
3860 self.assertIn(curve, curves)
3861
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003862 def test_does_not_contain(self):
3863 """
3864 The ``in`` operator reports that a :py:type:`set` not containing a
3865 curve does not contain that curve.
3866 """
3867 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003868 curves = set([
3869 get_elliptic_curve(self.curve_factory.another_curve_name)
3870 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003871 self.assertNotIn(curve, curves)
3872
3873
Rick Dean5b7b6372009-04-01 11:34:06 -05003874if __name__ == '__main__':
3875 main()