blob: 5b2c48a5e37eb661d2a582fa1b5453bef61359db [file] [log] [blame]
Jean-Paul Calderone8671c852011-03-02 19:26:20 -05001# Copyright (c) Jean-Paul Calderone
2# See LICENSE file for details.
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04003
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05004"""
Jonathan Ballet648875f2011-07-16 14:14:58 +09005Unit tests for :py:mod:`OpenSSL.crypto`.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05006"""
7
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04008from unittest import main
Jean-Paul Calderone60432792015-04-13 12:26:07 -04009from warnings import catch_warnings, simplefilter
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -040010
Alex Gaynor4b9c96a2014-08-14 09:51:48 -070011import base64
12import os
13import re
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -040014from subprocess import PIPE, Popen
Rick Dean47262da2009-07-08 16:17:17 -050015from datetime import datetime, timedelta
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050016
Alex Gaynor791212d2015-09-05 15:46:08 -040017import pytest
18
Alex Gaynorb8e38992015-09-04 08:14:04 -040019from six import u, b, binary_type
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050020
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050021from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050022from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
Alex Gaynor31287502015-09-05 16:11:27 -040023from OpenSSL.crypto import (
Dan Sully44e767a2016-06-04 18:05:27 -070024 X509Store,
25 X509StoreFlags,
26 X509StoreType,
27 X509StoreContext,
28 X509StoreContextError
Alex Gaynor31287502015-09-05 16:11:27 -040029)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070030from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -050031from OpenSSL.crypto import X509Extension, X509ExtensionType
Rick Dean5b7b6372009-04-01 11:34:06 -050032from OpenSSL.crypto import load_certificate, load_privatekey
Cory Benfield6492f7c2015-10-27 16:57:58 +090033from OpenSSL.crypto import load_publickey, dump_publickey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040034from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040035from OpenSSL.crypto import dump_certificate, load_certificate_request
36from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040037from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Jean-Paul Calderone9178ee62010-01-25 17:55:30 -050038from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000039from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040040from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040041from OpenSSL.crypto import (
42 sign, verify, get_elliptic_curve, get_elliptic_curves)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020043from OpenSSL._util import native, lib
44
45from .util import (
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040046 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
47)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040048
Alex Gaynoraceb3e22015-09-05 12:00:22 -040049
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040050def normalize_certificate_pem(pem):
51 return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
52
53
54def normalize_privatekey_pem(pem):
55 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
56
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040057
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050058GOOD_CIPHER = "blowfish"
59BAD_CIPHER = "zippers"
60
Anthony Alba2ce737f2015-12-04 11:04:56 +080061GOOD_DIGEST = "SHA1"
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050062BAD_DIGEST = "monkeys"
63
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040064root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050065MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
66BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
67ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
68NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
69MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
70ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
71urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
722xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
731dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
74FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
75VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
76BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
77b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
78AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
79hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
80w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
81-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040082""")
Rick Dean94e46fd2009-07-18 14:51:24 -050083
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040084root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050085MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
86jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
873claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
88AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
89yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
906JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
91BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
92u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
93PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
94I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
95ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
966AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
97cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
98-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040099""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500100
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700101intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
102MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
103WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
104DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
105ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
106dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
107MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
108AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
109FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
11021H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
111AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
112QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1139n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1149mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
115-----END CERTIFICATE-----
116""")
117
118intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
119MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
120ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
121qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
122AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
123rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
124147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
125+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
126wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
127sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
12852vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
129DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
130/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
131NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
132-----END RSA PRIVATE KEY-----
133""")
134
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400135server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500136MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
137BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
138VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
139NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
140gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
141lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
142b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
143lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
144gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
145dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1462mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
147uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
148-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400149""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500150
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400151server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500152MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
153U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
154SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
155AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
156j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
157j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
158Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
159msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
160FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1614e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1621sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
163NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
164r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
165-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400166"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500167
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700168intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
169MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
170ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
171CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
172biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
173BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
174CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
175biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
176iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
177+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
178biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
179UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1803bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
181x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
182-----END CERTIFICATE-----
183""")
184
185intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
186MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
187SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1888Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
189AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1905ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
191d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
192z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
193dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
194EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
195X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
1969UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
197ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
198nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
199-----END RSA PRIVATE KEY-----
200""")
201
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400202client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500203MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
204BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
205VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
206ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
207MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
208rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
209iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
210oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2110fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
212Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2139Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
214PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
215-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400216""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500217
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400218client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500219MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
220btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
221eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
222AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
223zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
224h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
225V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
226TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
227dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
228D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
229si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
230JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
231f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
232-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400233"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400234
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400235cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400236MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
237BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
238ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
239NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
240MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
241ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
242urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2432xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2441dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
245FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
246VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
247BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
248b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
249AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
250hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
251w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
252-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400253""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400254
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400255cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
256-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400257MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
258jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2593claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
260AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
261yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2626JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
263BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
264u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
265PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
266I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
267ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2686AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
269cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
270-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400271"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400272
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400273cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
274MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
275EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
276ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
277BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
278E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
279xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
280gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
281Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
282oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
283-----END CERTIFICATE REQUEST-----
284""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500285
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400286encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400287Proc-Type: 4,ENCRYPTED
288DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400289
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400290SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
291a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2928+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
293mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
294+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
295fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
296tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
297rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
298gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
299o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
3007SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
301MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
30211n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
303-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400304""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400305
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400306encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400307
Cory Benfield6492f7c2015-10-27 16:57:58 +0900308
309cleartextPublicKeyPEM = b("""-----BEGIN PUBLIC KEY-----
310MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
311gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
31290qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
313ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
314XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
3158Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
316ywIDAQAB
317-----END PUBLIC KEY-----
318""")
319
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400320# Some PKCS#7 stuff. Generated with the openssl command line:
321#
322# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
323#
324# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400325pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400326-----BEGIN PKCS7-----
327MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
328BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
329A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
330MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
331cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
332A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
333HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
334SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
335zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
336LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
337A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
33865w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
339Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
340Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
341bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
342VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
343/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
344Ho4EzbYCOaEAMQA=
345-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400346""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400347
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700348pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700349MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
350BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
351A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
352MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
353cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
354A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
355HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
356SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
357zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
358LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
359A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
36065w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
361Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
362Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
363bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
364VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
365/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
366Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700367""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700368
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400369crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500370-----BEGIN X509 CRL-----
371MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
372SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
373D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
374MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
375MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3764dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3770yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
378vrzEeLDRiiPl92dyyWmu
379-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400380""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400381
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400382crlDataUnsupportedExtension = b("""\
383-----BEGIN X509 CRL-----
384MIIGRzCCBS8CAQIwDQYJKoZIhvcNAQELBQAwJzELMAkGA1UEBhMCVVMxGDAWBgNV
385BAMMD2NyeXB0b2dyYXBoeS5pbxgPMjAxNTAxMDEwMDAwMDBaGA8yMDE2MDEwMTAw
386MDAwMFowggTOMBQCAQAYDzIwMTUwMTAxMDAwMDAwWjByAgEBGA8yMDE1MDEwMTAw
387MDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAn
388MQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQD
389CgEAMHICAQIYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAw
390MDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlw
391dG9ncmFwaHkuaW8wCgYDVR0VBAMKAQEwcgIBAxgPMjAxNTAxMDEwMDAwMDBaMFww
392GAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTArpCkwJzELMAkGA1UE
393BhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNVHRUEAwoBAjByAgEE
394GA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQG
395A1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5
396LmlvMAoGA1UdFQQDCgEDMHICAQUYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQR
397GA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgw
398FgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQQwcgIBBhgPMjAxNTAx
399MDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTAr
400pCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNV
401HRUEAwoBBTByAgEHGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAx
402MDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwP
403Y3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEGMHICAQgYDzIwMTUwMTAxMDAwMDAw
404WjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJ
405BgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQgw
406cgIBCRgPMjAxNTAxMDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAw
407WjA0BgNVHR0ELTArpCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dy
408YXBoeS5pbzAKBgNVHRUEAwoBCTByAgEKGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNV
409HRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJV
410UzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEKMC4CAQsYDzIw
411MTUwMTAxMDAwMDAwWjAYMAoGA1UdFQQDCgEBMAoGAyoDBAQDCgEAMA0GCSqGSIb3
412DQEBCwUAA4IBAQBTaloHlPaCZzYee8LxkWej5meiqxQVNWFoVdjesroa+f1FRrH+
413drRU60Nq97KCKf7f9GNN/J3ZIlQmYhmuDqh12f+XLpotoj1ZRfBz2hjFCkJlv+2c
414oWWGNHgA70ndFoVtcmX088SYpX8E3ARATivS4q2h9WlwV6rO93mhg3HGIe3JpcK4
4157BcW6Poi/ut/zsDOkVbI00SqaujRpdmdCTht82MH3ztjyDkI9KYaD/YEweKSrWOz
416SdEILd164bfBeLuplVI+xpmTEMVNpXBlSXl7+xIw9Vk7p7Q1Pa3k/SvhOldYCm6y
417C1xAg/AAq6w78yzYt18j5Mj0s6eeHi1YpHKw
418-----END X509 CRL-----
419""")
420
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400421
422# A broken RSA private key which can be used to test the error path through
423# PKey.check.
424inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
425MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
4265kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
427OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
428zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
429nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
430HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
431oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
432-----END RSA PRIVATE KEY-----
433""")
434
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400435# certificate with NULL bytes in subjectAltName and common name
436
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400437nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400438MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
439DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
440eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
441RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
442ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
443NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
444DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
445ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
446ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
447hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
448BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
449pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
450vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
451KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
452oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
45308LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
454HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
455BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
456Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
457bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
458AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
459i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
460HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
461kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
462VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
463RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
464-----END CERTIFICATE-----""")
465
Colleen Murphye09399b2016-03-01 17:40:49 -0800466large_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
467MIIJYgIBAAKCAg4AtRua8eIeevRfsj+fkcHr1vmse7Kgb+oX1ssJAvCb1R7JQMnH
468hNDjDP6b3vEkZuPUzlDHymP+cNkXvvi4wJ4miVbO3+SeU4Sh+jmsHeHzGIXat9xW
4699PFtuPM5FQq8zvkY8aDeRYmYwN9JKu4/neMBCBqostYlTEWg+bSytO/qWnyHTHKh
470g0GfaDdqUQPsGQw+J0MgaYIjQOCVASHAPlzbDQLCtuOb587rwTLkZA2GwoHB/LyJ
471BwT0HHgBaiObE12Vs6wi2en0Uu11CiwEuK1KIBcZ2XbE6eApaZa6VH9ysEmUxPt7
472TqyZ4E2oMIYaLPNRxuvozdwTlj1svI1k1FrkaXGc5MTjbgigPMKjIb0T7b/4GNzt
473DhP1LvAeUMnrEi3hJJrcJPXHPqS8/RiytR9xQQW6Sdh4LaA3f9MQm3WSevWage3G
474P8YcCLssOVKsArDjuA52NF5LmYuAeUzXprm4ITDi2oO+0iFBpFW6VPEK4A9vO0Yk
475M/6Wt6tG8zyWhaSH1zFUTwfQ9Yvjyt5w1lrUaAJuoTpwbMVZaDJaEhjOaXU0dyPQ
476jOsePDOQcU6dkeTWsQ3LsHPEEug/X6819TLG5mb3V7bvV9nPFBfTJSCEG794kr90
477XgZfIN71FrdByxLerlbuJI21pPs/nZi9SXi9jAWeiS45/azUxMsyYgJArui+gjq7
478sV1pWiBm6/orAgMBAAECggINQp5L6Yu+oIXBqcSjgq8tfF9M5hd30pLuf/EheHZf
479LA7uAqn2fVGFI2OInIJhXIOT5OxsAXO0xXfltzawZxIFpOFMqajj4F7aYjvSpw9V
480J4EdSiJ/zgv8y1qUdbwEZbHVThRZjoSlrtSzilonBoHZAE0mHtqMz7iRFSk1zz6t
481GunRrvo/lROPentf3TsvHquVNUYI5yaapyO1S7xJhecMIIYSb8nbsHI54FBDGNas
4826mFmpPwI/47/6HTwOEWupnn3NicsjrHzUInOUpaMig4cRR+aP5bjqg/ty8xI8AoN
483evEmCytiWTc+Rvbp1ieN+1jpjN18PjUk80/W7qioHUDt4ieLic8uxWH2VD9SCEnX
484Mpi9tA/FqoZ+2A/3m1OfrY6jiZVE2g+asi9lCK7QVWL39eK82H4rPvtp0/dyo1/i
485ZZz68TXg+m8IgEZcp88hngbkuoTTzpGE73QuPKhGA1uMIimDdqPPB5WP76q+03Oi
486IRR5DfZnqPERed49by0enJ7tKa/gFPZizOV8ALKr0Dp+vfAkxGDLPLBLd2A3//tw
487xg0Q/wltihHSBujv4nYlDXdc5oYyMYZ+Lhc/VuOghHfBq3tgEQ1ECM/ofqXEIdy7
488nVcpZn3Eeq8Jl5CrqxE1ee3NxlzsJHn99yGQpr7mOhW/psJF3XNz80Meg3L4m1T8
489sMBK0GbaassuJhdzb5whAoIBBw48sx1b1WR4XxQc5O/HjHva+l16i2pjUnOUTcDF
490RWmSbIhBm2QQ2rVhO8+fak0tkl6ZnMWW4i0U/X5LOEBbC7+IS8bO3j3Revi+Vw5x
491j96LMlIe9XEub5i/saEWgiz7maCvfzLFU08e1OpT4qPDpP293V400ubA6R7WQTCv
492pBkskGwHeu0l/TuKkVqBFFUTu7KEbps8Gjg7MkJaFriAOv1zis/umK8pVS3ZAM6e
4938w5jfpRccn8Xzta2fRwTB5kCmfxdDsY0oYGxPLRAbW72bORoLGuyyPp/ojeGwoik
494JX9RttErc6FjyZtks370Pa8UL5QskyhMbDhrZW2jFD+RXYM1BrvmZRjbAoIBBwy4
495iFJpuDfytJfz1MWtaL5DqEL/kmiZYAXl6hifNhGu5GAipVIIGsDqEYW4i+VC15aa
4967kOCwz/I5zsB3vSDW96IRs4wXtqEZSibc2W/bqfVi+xcvPPl1ZhQ2EAwa4D/x035
497kyf20ffWOU+1yf2cnijzqs3IzlveUm+meLw5s3Rc+iG7DPWWeCoe1hVwANI1euNc
498pqKwKY905yFyjOje2OgiEU2kS4YME4zGeBys8yo7E42hNnN2EPK6xkkUqzdudLLQ
4998OUlKRTc8AbIf3XG1rpA4VUpTv3hhxGGwCRy6If8zgZQsNYchgNztRGk72Gcb8Dm
500vFSEN3ZtwxU64G3YZzntdcr2WPzxAoIBBw30g6Fgdb/gmVnOpL0//T0ePNDKIMPs
501jVJLaRduhoZgB1Bb9qPUPX0SzRzLZtg1tkZSDjBDoHmOHJfhxUaXt+FLCPPbrE4t
502+nq9n/nBaMM779w9ClqhqLOyGrwKoxjSmhi+TVEHyIxCbXMvPHVHfX9WzxjbcGrN
503ZvRaEVZWo+QlIX8yqdSwqxLk1WtAIRzvlcj7NKum8xBxPed6BNFep/PtgIAmoLT5
504L8wb7EWb2iUdc2KbZ4OaY51lDScqpATgXu3WjXfM+Q52G0mX6Wyd0cjlL711Zrjb
505yLbiueZT94lgIHHRRKtKc8CEqcjkQV5OzABS3P/gQSfgZXBdLKjOpTnKDUq7IBeH
506AoIBBweAOEIAPLQg1QRUrr3xRrYKRwlakgZDii9wJt1l5AgBTICzbTA1vzDJ1JM5
507AqSpCV6w9JWyYVcXK+HLdKBRZLaPPNEQDJ5lOxD6uMziWGl2rg8tj+1xNMWfxiPz
508aTCjoe4EoBUMoTq2gwzRcM2usEQNikXVhnj9Wzaivsaeb4bJ3GRPW5DkrO6JSEtT
509w+gvyMqQM2Hy5k7E7BT46sXVwaj/jZxuqGnebRixXtnp0WixdRIqYWUr1UqLf6hQ
510G7WP2BgoxCMaCmNW8+HMD/xuxucEotoIhZ+GgJKBFoNnjl3BX+qxYdSe9RbL/5Tr
5114It6Jxtj8uETJXEbv9Cg6v1agWPS9YY8RLTBAoIBBwrU2AsAUts6h1LgGLKK3UWZ
512oLH5E+4o+7HqSGRcRodVeN9NBXIYdHHOLeEG6YNGJiJ3bFP5ZQEu9iDsyoFVKJ9O
513Mw/y6dKZuxOCZ+X8FopSROg3yWfdOpAm6cnQZp3WqLNX4n/Q6WvKojfyEiPphjwT
5140ymrUJELXLWJmjUyPoAk6HgC0Gs28ZnEXbyhx7CSbZNFyCU/PNUDZwto3GisIPD3
515le7YjqHugezmjMGlA0sDw5aCXjfbl74vowRFYMO6e3ItApfSRgNV86CDoX74WI/5
516AYU/QVM4wGt8XGT2KwDFJaxYGKsGDMWmXY04dS+WPuetCbouWUusyFwRb9SzFave
517vYeU7Ab/
518-----END RSA PRIVATE KEY-----""")
519
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400520
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400521class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400522 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900523 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400524 """
525
526 def setUp(self):
527 """
528 Create a new private key and start a certificate request (for a test
529 method to finish in one way or another).
530 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800531 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400532 # Basic setup stuff to generate a certificate
533 self.pkey = PKey()
534 self.pkey.generate_key(TYPE_RSA, 384)
535 self.req = X509Req()
536 self.req.set_pubkey(self.pkey)
537 # Authority good you have.
538 self.req.get_subject().commonName = "Yoda root CA"
539 self.x509 = X509()
540 self.subject = self.x509.get_subject()
541 self.subject.commonName = self.req.get_subject().commonName
542 self.x509.set_issuer(self.subject)
543 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400544 now = datetime.now()
545 expire = datetime.now() + timedelta(days=100)
546 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
547 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400548
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800549 def tearDown(self):
550 """
551 Forget all of the pyOpenSSL objects so they can be garbage collected,
552 their memory released, and not interfere with the leak detection code.
553 """
554 self.pkey = self.req = self.x509 = self.subject = None
555 super(X509ExtTests, self).tearDown()
556
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400557 def test_str(self):
558 """
Alex Gaynor31287502015-09-05 16:11:27 -0400559 The string representation of :py:class:`X509Extension` instances as
560 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400561 """
562 # This isn't necessarily the best string representation. Perhaps it
563 # will be changed/improved in the future.
564 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400565 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400566 'CA:FALSE')
567
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400568 def test_type(self):
569 """
Alex Gaynor31287502015-09-05 16:11:27 -0400570 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
571 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400572 """
573 self.assertIdentical(X509Extension, X509ExtensionType)
574 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400575 X509Extension,
576 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400577
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500578 def test_construction(self):
579 """
Alex Gaynor31287502015-09-05 16:11:27 -0400580 :py:class:`X509Extension` accepts an extension type name, a critical
581 flag, and an extension value and returns an
582 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500583 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400584 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500585 self.assertTrue(
586 isinstance(basic, X509ExtensionType),
587 "%r is of type %r, should be %r" % (
588 basic, type(basic), X509ExtensionType))
589
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400590 comment = X509Extension(
591 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500592 self.assertTrue(
593 isinstance(comment, X509ExtensionType),
594 "%r is of type %r, should be %r" % (
595 comment, type(comment), X509ExtensionType))
596
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500597 def test_invalid_extension(self):
598 """
Alex Gaynor31287502015-09-05 16:11:27 -0400599 :py:class:`X509Extension` raises something if it is passed a bad
600 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500601 """
602 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400603 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500604 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400605 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500606
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500607 # Exercise a weird one (an extension which uses the r2i method). This
608 # exercises the codepath that requires a non-NULL ctx to be passed to
609 # X509V3_EXT_nconf. It can't work now because we provide no
610 # configuration database. It might be made to work in the future.
611 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400612 Error, X509Extension, b('proxyCertInfo'), True,
613 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500614
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500615 def test_get_critical(self):
616 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900617 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500618 extension's critical flag.
619 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400620 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500621 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400622 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500623 self.assertFalse(ext.get_critical())
624
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500625 def test_get_short_name(self):
626 """
Alex Gaynor31287502015-09-05 16:11:27 -0400627 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
628 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500629 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400630 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
631 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
632 ext = X509Extension(b('nsComment'), True, b('foo bar'))
633 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500634
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400635 def test_get_data(self):
636 """
Alex Gaynor31287502015-09-05 16:11:27 -0400637 :py:meth:`X509Extension.get_data` returns a string giving the data of
638 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400639 """
640 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
641 # Expect to get back the DER encoded form of CA:true.
642 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
643
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400644 def test_get_data_wrong_args(self):
645 """
Alex Gaynor31287502015-09-05 16:11:27 -0400646 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
647 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400648 """
649 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
650 self.assertRaises(TypeError, ext.get_data, None)
651 self.assertRaises(TypeError, ext.get_data, "foo")
652 self.assertRaises(TypeError, ext.get_data, 7)
653
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400654 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500655 """
Alex Gaynor31287502015-09-05 16:11:27 -0400656 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
657 provided for an extension which does not use it and is ignored in this
658 case.
Rick Dean47262da2009-07-08 16:17:17 -0500659 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400660 ext1 = X509Extension(
661 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400662 self.x509.add_extensions([ext1])
663 self.x509.sign(self.pkey, 'sha1')
664 # This is a little lame. Can we think of a better way?
665 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400666 self.assertTrue(b('X509v3 Basic Constraints:') in text)
667 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400668
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400669 def test_subject(self):
670 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900671 If an extension requires a subject, the :py:data:`subject` parameter to
672 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400673 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400674 ext3 = X509Extension(
675 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400676 self.x509.add_extensions([ext3])
677 self.x509.sign(self.pkey, 'sha1')
678 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400679 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400680
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400681 def test_missing_subject(self):
682 """
Alex Gaynor31287502015-09-05 16:11:27 -0400683 If an extension requires a subject and the :py:data:`subject` parameter
684 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400685 """
686 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400687 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400688
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400689 def test_invalid_subject(self):
690 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900691 If the :py:data:`subject` parameter is given a value which is not an
692 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400693 """
694 for badObj in [True, object(), "hello", [], self]:
695 self.assertRaises(
696 TypeError,
697 X509Extension,
698 'basicConstraints', False, 'CA:TRUE', subject=badObj)
699
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400700 def test_unused_issuer(self):
701 """
Alex Gaynor31287502015-09-05 16:11:27 -0400702 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
703 provided for an extension which does not use it and is ignored in this
704 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400705 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400706 ext1 = X509Extension(
707 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400708 self.x509.add_extensions([ext1])
709 self.x509.sign(self.pkey, 'sha1')
710 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400711 self.assertTrue(b('X509v3 Basic Constraints:') in text)
712 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400713
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400714 def test_issuer(self):
715 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800716 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900717 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400718 """
719 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400720 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400721 issuer=self.x509)
722 self.x509.add_extensions([ext2])
723 self.x509.sign(self.pkey, 'sha1')
724 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400725 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
726 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400727
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400728 def test_missing_issuer(self):
729 """
Alex Gaynor31287502015-09-05 16:11:27 -0400730 If an extension requires an issue and the :py:data:`issuer` parameter
731 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400732 """
733 self.assertRaises(
734 Error,
735 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400736 b('authorityKeyIdentifier'), False,
737 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400738
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400739 def test_invalid_issuer(self):
740 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900741 If the :py:data:`issuer` parameter is given a value which is not an
742 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400743 """
744 for badObj in [True, object(), "hello", [], self]:
745 self.assertRaises(
746 TypeError,
747 X509Extension,
748 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
749 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500750
751
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400752class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500753 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900754 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500755 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400756
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400757 def test_type(self):
758 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900759 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
760 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400761 """
762 self.assertIdentical(PKey, PKeyType)
763 self.assertConsistentType(PKey, 'PKey')
764
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500765 def test_construction(self):
766 """
Alex Gaynor31287502015-09-05 16:11:27 -0400767 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
768 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500769 """
770 self.assertRaises(TypeError, PKey, None)
771 key = PKey()
772 self.assertTrue(
773 isinstance(key, PKeyType),
774 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
775
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500776 def test_pregeneration(self):
777 """
Alex Gaynor31287502015-09-05 16:11:27 -0400778 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
779 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
780 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500781 """
782 key = PKey()
783 self.assertEqual(key.type(), 0)
784 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400785 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500786
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500787 def test_failedGeneration(self):
788 """
Alex Gaynor31287502015-09-05 16:11:27 -0400789 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
790 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
791 the second giving the number of bits to generate. If an invalid type
792 is specified or generation fails, :py:exc:`Error` is raised. If an
793 invalid number of bits is specified, :py:exc:`ValueError` or
794 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500795 """
796 key = PKey()
797 self.assertRaises(TypeError, key.generate_key)
798 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
799 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
800 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500801
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500802 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
803 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500804
Alex Gaynor5bb2bd12016-07-03 10:48:32 -0400805 with pytest.raises(TypeError):
806 key.generate_key(TYPE_RSA, object())
807
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500808 # XXX RSA generation for small values of bits is fairly buggy in a wide
809 # range of OpenSSL versions. I need to figure out what the safe lower
810 # bound for a reasonable number of OpenSSL versions is and explicitly
811 # check for that in the wrapper. The failure behavior is typically an
812 # infinite loop inside OpenSSL.
813
814 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500815
816 # XXX DSA generation seems happy with any number of bits. The DSS
817 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
818 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500819 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500820 # So, it doesn't seem possible to make generate_key fail for
821 # TYPE_DSA with a bits argument which is at least an int.
822
823 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
824
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500825 def test_rsaGeneration(self):
826 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900827 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
828 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500829 """
830 bits = 128
831 key = PKey()
832 key.generate_key(TYPE_RSA, bits)
833 self.assertEqual(key.type(), TYPE_RSA)
834 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400835 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500836
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500837 def test_dsaGeneration(self):
838 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900839 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
840 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500841 """
842 # 512 is a magic number. The DSS (Digital Signature Standard)
843 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
844 # will silently promote any value below 512 to 512.
845 bits = 512
846 key = PKey()
847 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800848 # self.assertEqual(key.type(), TYPE_DSA)
849 # self.assertEqual(key.bits(), bits)
850 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500851
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500852 def test_regeneration(self):
853 """
Alex Gaynor31287502015-09-05 16:11:27 -0400854 :py:meth:`PKeyType.generate_key` can be called multiple times on the
855 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500856 """
857 key = PKey()
858 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400859 key.generate_key(type, bits)
860 self.assertEqual(key.type(), type)
861 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500862
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400863 def test_inconsistentKey(self):
864 """
Alex Gaynor31287502015-09-05 16:11:27 -0400865 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
866 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400867 """
868 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400869 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400870
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400871 def test_check_wrong_args(self):
872 """
Alex Gaynor31287502015-09-05 16:11:27 -0400873 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
874 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400875 """
876 self.assertRaises(TypeError, PKey().check, None)
877 self.assertRaises(TypeError, PKey().check, object())
878 self.assertRaises(TypeError, PKey().check, 1)
879
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400880 def test_check_public_key(self):
881 """
882 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
883 part of the key is available.
884 """
885 # A trick to get a public-only key
886 key = PKey()
887 key.generate_key(TYPE_RSA, 512)
888 cert = X509()
889 cert.set_pubkey(key)
890 pub = cert.get_pubkey()
891 self.assertRaises(TypeError, pub.check)
892
893
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400894class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500895 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900896 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500897 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400898
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500899 def _x509name(self, **attrs):
900 # XXX There's no other way to get a new X509Name yet.
901 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400902 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400903
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500904 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400905 def key(attr):
906 return attr[1]
907 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500908 for k, v in attrs:
909 setattr(name, k, v)
910 return name
911
Rick Deane15b1472009-07-09 15:53:42 -0500912 def test_type(self):
913 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900914 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500915 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400916 self.assertIdentical(X509Name, X509NameType)
917 self.assertEqual(X509NameType.__name__, 'X509Name')
918 self.assertTrue(isinstance(X509NameType, type))
919
Rick Deane15b1472009-07-09 15:53:42 -0500920 name = self._x509name()
921 self.assertTrue(
922 isinstance(name, X509NameType),
923 "%r is of type %r, should be %r" % (
924 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500925
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400926 def test_onlyStringAttributes(self):
927 """
Alex Gaynor31287502015-09-05 16:11:27 -0400928 Attempting to set a non-:py:data:`str` attribute name on an
929 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
930 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400931 """
932 name = self._x509name()
933 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400934 # rejected. Sorry, you're wrong. unicode is automatically converted
935 # to str outside of the control of X509Name, so there's no way to
936 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800937
Alex Gaynor31287502015-09-05 16:11:27 -0400938 # Also, this used to test str subclasses, but that test is less
939 # relevant now that the implementation is in Python instead of C. Also
940 # PyPy automatically converts str subclasses to str when they are
941 # passed to setattr, so we can't test it on PyPy. Apparently CPython
942 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400943 self.assertRaises(TypeError, setattr, name, None, "hello")
944 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400945
946 def test_setInvalidAttribute(self):
947 """
Alex Gaynor31287502015-09-05 16:11:27 -0400948 Attempting to set any attribute name on an :py:class:`X509NameType`
949 instance for which no corresponding NID is defined causes
950 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400951 """
952 name = self._x509name()
953 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
954
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500955 def test_attributes(self):
956 """
Alex Gaynor31287502015-09-05 16:11:27 -0400957 :py:class:`X509NameType` instances have attributes for each standard
958 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500959 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500960 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500961 name.commonName = "foo"
962 self.assertEqual(name.commonName, "foo")
963 self.assertEqual(name.CN, "foo")
964 name.CN = "baz"
965 self.assertEqual(name.commonName, "baz")
966 self.assertEqual(name.CN, "baz")
967 name.commonName = "bar"
968 self.assertEqual(name.commonName, "bar")
969 self.assertEqual(name.CN, "bar")
970 name.CN = "quux"
971 self.assertEqual(name.commonName, "quux")
972 self.assertEqual(name.CN, "quux")
973
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500974 def test_copy(self):
975 """
Alex Gaynor31287502015-09-05 16:11:27 -0400976 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
977 with all the same attributes as an existing :py:class:`X509NameType`
978 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500979 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500980 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500981
982 copy = X509Name(name)
983 self.assertEqual(copy.commonName, "foo")
984 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500985
986 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500987 copy.commonName = "baz"
988 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500989
990 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500991 name.emailAddress = "quux@example.com"
992 self.assertEqual(copy.emailAddress, "bar@example.com")
993
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500994 def test_repr(self):
995 """
Alex Gaynor31287502015-09-05 16:11:27 -0400996 :py:func:`repr` passed an :py:class:`X509NameType` instance should
997 return a string containing a description of the type and the NIDs which
998 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500999 """
1000 name = self._x509name(commonName="foo", emailAddress="bar")
1001 self.assertEqual(
1002 repr(name),
1003 "<X509Name object '/emailAddress=bar/CN=foo'>")
1004
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001005 def test_comparison(self):
1006 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001007 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001008 """
1009 def _equality(a, b, assertTrue, assertFalse):
1010 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
1011 assertFalse(a != b)
1012 assertTrue(b == a)
1013 assertFalse(b != a)
1014
1015 def assertEqual(a, b):
1016 _equality(a, b, self.assertTrue, self.assertFalse)
1017
1018 # Instances compare equal to themselves.
1019 name = self._x509name()
1020 assertEqual(name, name)
1021
1022 # Empty instances should compare equal to each other.
1023 assertEqual(self._x509name(), self._x509name())
1024
1025 # Instances with equal NIDs should compare equal to each other.
1026 assertEqual(self._x509name(commonName="foo"),
1027 self._x509name(commonName="foo"))
1028
1029 # Instance with equal NIDs set using different aliases should compare
1030 # equal to each other.
1031 assertEqual(self._x509name(commonName="foo"),
1032 self._x509name(CN="foo"))
1033
1034 # Instances with more than one NID with the same values should compare
1035 # equal to each other.
1036 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
1037 self._x509name(commonName="foo", OU="bar"))
1038
1039 def assertNotEqual(a, b):
1040 _equality(a, b, self.assertFalse, self.assertTrue)
1041
1042 # Instances with different values for the same NID should not compare
1043 # equal to each other.
1044 assertNotEqual(self._x509name(CN="foo"),
1045 self._x509name(CN="bar"))
1046
1047 # Instances with different NIDs should not compare equal to each other.
1048 assertNotEqual(self._x509name(CN="foo"),
1049 self._x509name(OU="foo"))
1050
1051 def _inequality(a, b, assertTrue, assertFalse):
1052 assertTrue(a < b)
1053 assertTrue(a <= b)
1054 assertTrue(b > a)
1055 assertTrue(b >= a)
1056 assertFalse(a > b)
1057 assertFalse(a >= b)
1058 assertFalse(b < a)
1059 assertFalse(b <= a)
1060
1061 def assertLessThan(a, b):
1062 _inequality(a, b, self.assertTrue, self.assertFalse)
1063
1064 # An X509Name with a NID with a value which sorts less than the value
1065 # of the same NID on another X509Name compares less than the other
1066 # X509Name.
1067 assertLessThan(self._x509name(CN="abc"),
1068 self._x509name(CN="def"))
1069
1070 def assertGreaterThan(a, b):
1071 _inequality(a, b, self.assertFalse, self.assertTrue)
1072
1073 # An X509Name with a NID with a value which sorts greater than the
1074 # value of the same NID on another X509Name compares greater than the
1075 # other X509Name.
1076 assertGreaterThan(self._x509name(CN="def"),
1077 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001078
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001079 def test_hash(self):
1080 """
Alex Gaynor31287502015-09-05 16:11:27 -04001081 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1082 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001083 """
1084 a = self._x509name(CN="foo")
1085 b = self._x509name(CN="foo")
1086 self.assertEqual(a.hash(), b.hash())
1087 a.CN = "bar"
1088 self.assertNotEqual(a.hash(), b.hash())
1089
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001090 def test_der(self):
1091 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001092 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001093 """
1094 a = self._x509name(CN="foo", C="US")
1095 self.assertEqual(
1096 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001097 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001098 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001099
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001100 def test_get_components(self):
1101 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001102 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1103 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001104 giving the NIDs and associated values which make up the name.
1105 """
1106 a = self._x509name()
1107 self.assertEqual(a.get_components(), [])
1108 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001109 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001110 a.organizationalUnitName = "bar"
1111 self.assertEqual(
1112 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001113 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001114
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001115 def test_load_nul_byte_attribute(self):
1116 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001117 An :py:class:`OpenSSL.crypto.X509Name` from an
1118 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001119 NUL byte in the value of one of its attributes.
1120 """
1121 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1122 subject = cert.get_subject()
1123 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001124 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001125
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001126 def test_setAttributeFailure(self):
1127 """
1128 If the value of an attribute cannot be set for some reason then
1129 :py:class:`OpenSSL.crypto.Error` is raised.
1130 """
1131 name = self._x509name()
1132 # This value is too long
1133 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1134
1135
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001136class _PKeyInteractionTestsMixin:
1137 """
1138 Tests which involve another thing and a PKey.
1139 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001140
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001141 def signable(self):
1142 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001143 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1144 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001145 """
1146 raise NotImplementedError()
1147
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001148 def test_signWithUngenerated(self):
1149 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001150 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1151 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001152 """
1153 request = self.signable()
1154 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001155 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001156
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001157 def test_signWithPublicKey(self):
1158 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001159 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1160 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001161 """
1162 request = self.signable()
1163 key = PKey()
1164 key.generate_key(TYPE_RSA, 512)
1165 request.set_pubkey(key)
1166 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001167 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001168
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001169 def test_signWithUnknownDigest(self):
1170 """
Alex Gaynor31287502015-09-05 16:11:27 -04001171 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1172 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001173 """
1174 request = self.signable()
1175 key = PKey()
1176 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001177 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001178
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001179 def test_sign(self):
1180 """
Alex Gaynor31287502015-09-05 16:11:27 -04001181 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1182 valid digest function. :py:meth:`X509Req.verify` can be used to check
1183 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001184 """
1185 request = self.signable()
1186 key = PKey()
1187 key.generate_key(TYPE_RSA, 512)
1188 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001189 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001190 # If the type has a verify method, cover that too.
1191 if getattr(request, 'verify', None) is not None:
1192 pub = request.get_pubkey()
1193 self.assertTrue(request.verify(pub))
1194 # Make another key that won't verify.
1195 key = PKey()
1196 key.generate_key(TYPE_RSA, 512)
1197 self.assertRaises(Error, request.verify, key)
1198
1199
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001200class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001201 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001202 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001203 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001204
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001205 def signable(self):
1206 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001207 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001208 """
1209 return X509Req()
1210
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001211 def test_type(self):
1212 """
Alex Gaynor31287502015-09-05 16:11:27 -04001213 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1214 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001215 """
1216 self.assertIdentical(X509Req, X509ReqType)
1217 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001218
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001219 def test_construction(self):
1220 """
Alex Gaynor31287502015-09-05 16:11:27 -04001221 :py:obj:`X509Req` takes no arguments and returns an
1222 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001223 """
1224 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001225 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001226
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001227 def test_version(self):
1228 """
Alex Gaynor31287502015-09-05 16:11:27 -04001229 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1230 certificate request. :py:obj:`X509ReqType.get_version` returns the
1231 X.509 version of the certificate request. The initial value of the
1232 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001233 """
1234 request = X509Req()
1235 self.assertEqual(request.get_version(), 0)
1236 request.set_version(1)
1237 self.assertEqual(request.get_version(), 1)
1238 request.set_version(3)
1239 self.assertEqual(request.get_version(), 3)
1240
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001241 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001242 """
Alex Gaynor31287502015-09-05 16:11:27 -04001243 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1244 with the wrong number of arguments or with a non-:py:obj:`int`
1245 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1246 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001247 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001248 request = X509Req()
1249 self.assertRaises(TypeError, request.set_version)
1250 self.assertRaises(TypeError, request.set_version, "foo")
1251 self.assertRaises(TypeError, request.set_version, 1, 2)
1252 self.assertRaises(TypeError, request.get_version, None)
1253
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001254 def test_get_subject(self):
1255 """
Alex Gaynor31287502015-09-05 16:11:27 -04001256 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1257 subject of the request and which is valid even after the request object
1258 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001259 """
1260 request = X509Req()
1261 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001262 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001263 subject.commonName = "foo"
1264 self.assertEqual(request.get_subject().commonName, "foo")
1265 del request
1266 subject.commonName = "bar"
1267 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001268
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001269 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001270 """
Alex Gaynor31287502015-09-05 16:11:27 -04001271 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1272 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001273 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001274 request = X509Req()
1275 self.assertRaises(TypeError, request.get_subject, None)
1276
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001277 def test_add_extensions(self):
1278 """
Alex Gaynor31287502015-09-05 16:11:27 -04001279 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1280 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001281 """
1282 request = X509Req()
1283 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001284 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001285 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001286 self.assertEqual(len(exts), 1)
1287 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1288 self.assertEqual(exts[0].get_critical(), 1)
1289 self.assertEqual(exts[0].get_data(), b('0\x00'))
1290
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001291 def test_get_extensions(self):
1292 """
1293 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1294 extensions added to this X509 request.
1295 """
1296 request = X509Req()
1297 exts = request.get_extensions()
1298 self.assertEqual(exts, [])
1299 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001300 X509Extension(b('basicConstraints'), True, b('CA:true')),
1301 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001302 exts = request.get_extensions()
1303 self.assertEqual(len(exts), 2)
1304 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1305 self.assertEqual(exts[0].get_critical(), 1)
1306 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1307 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1308 self.assertEqual(exts[1].get_critical(), 0)
1309 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001310
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001311 def test_add_extensions_wrong_args(self):
1312 """
Alex Gaynor31287502015-09-05 16:11:27 -04001313 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1314 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1315 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1316 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001317 """
1318 request = X509Req()
1319 self.assertRaises(TypeError, request.add_extensions)
1320 self.assertRaises(TypeError, request.add_extensions, object())
1321 self.assertRaises(ValueError, request.add_extensions, [object()])
1322 self.assertRaises(TypeError, request.add_extensions, [], None)
1323
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001324 def test_verify_wrong_args(self):
1325 """
1326 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1327 arguments or more than one argument or if passed anything other than a
1328 :py:obj:`PKey` instance as its single argument.
1329 """
1330 request = X509Req()
1331 self.assertRaises(TypeError, request.verify)
1332 self.assertRaises(TypeError, request.verify, object())
1333 self.assertRaises(TypeError, request.verify, PKey(), object())
1334
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001335 def test_verify_uninitialized_key(self):
1336 """
Alex Gaynor31287502015-09-05 16:11:27 -04001337 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1338 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001339 """
1340 request = X509Req()
1341 pkey = PKey()
1342 self.assertRaises(Error, request.verify, pkey)
1343
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001344 def test_verify_wrong_key(self):
1345 """
Alex Gaynor31287502015-09-05 16:11:27 -04001346 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1347 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1348 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001349 """
1350 request = X509Req()
1351 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001352 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001353 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1354 self.assertRaises(Error, request.verify, another_pkey)
1355
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001356 def test_verify_success(self):
1357 """
1358 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001359 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1360 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001361 """
1362 request = X509Req()
1363 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001364 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001365 self.assertEqual(True, request.verify(pkey))
1366
1367
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001368class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001369 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001370 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001371 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001372 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001373
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001374 extpem = """
1375-----BEGIN CERTIFICATE-----
1376MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1377BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1378eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1379MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1380aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1381hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1382Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1383zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1384hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1385TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
138603HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1387MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1388b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1389MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1390uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1391WpOdIpB8KksUTCzV591Nr1wd
1392-----END CERTIFICATE-----
1393 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001394
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001395 def signable(self):
1396 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001397 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001398 """
1399 return X509()
1400
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001401 def test_type(self):
1402 """
Alex Gaynor31287502015-09-05 16:11:27 -04001403 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1404 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001405 """
1406 self.assertIdentical(X509, X509Type)
1407 self.assertConsistentType(X509, 'X509')
1408
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001409 def test_construction(self):
1410 """
Alex Gaynor31287502015-09-05 16:11:27 -04001411 :py:obj:`X509` takes no arguments and returns an instance of
1412 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001413 """
1414 certificate = X509()
1415 self.assertTrue(
1416 isinstance(certificate, X509Type),
1417 "%r is of type %r, should be %r" % (certificate,
1418 type(certificate),
1419 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001420 self.assertEqual(type(X509Type).__name__, 'type')
1421 self.assertEqual(type(certificate).__name__, 'X509')
1422 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001423 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001424
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001425 def test_get_version_wrong_args(self):
1426 """
Alex Gaynor31287502015-09-05 16:11:27 -04001427 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1428 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001429 """
1430 cert = X509()
1431 self.assertRaises(TypeError, cert.get_version, None)
1432
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001433 def test_set_version_wrong_args(self):
1434 """
Alex Gaynor31287502015-09-05 16:11:27 -04001435 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1436 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001437 """
1438 cert = X509()
1439 self.assertRaises(TypeError, cert.set_version)
1440 self.assertRaises(TypeError, cert.set_version, None)
1441 self.assertRaises(TypeError, cert.set_version, 1, None)
1442
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001443 def test_version(self):
1444 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001445 :py:obj:`X509.set_version` sets the certificate version number.
1446 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001447 """
1448 cert = X509()
1449 cert.set_version(1234)
1450 self.assertEquals(cert.get_version(), 1234)
1451
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001452 def test_get_serial_number_wrong_args(self):
1453 """
Alex Gaynor31287502015-09-05 16:11:27 -04001454 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1455 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001456 """
1457 cert = X509()
1458 self.assertRaises(TypeError, cert.get_serial_number, None)
1459
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001460 def test_serial_number(self):
1461 """
Alex Gaynor31287502015-09-05 16:11:27 -04001462 The serial number of an :py:obj:`X509Type` can be retrieved and
1463 modified with :py:obj:`X509Type.get_serial_number` and
1464 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001465 """
1466 certificate = X509()
1467 self.assertRaises(TypeError, certificate.set_serial_number)
1468 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1469 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1470 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1471 self.assertEqual(certificate.get_serial_number(), 0)
1472 certificate.set_serial_number(1)
1473 self.assertEqual(certificate.get_serial_number(), 1)
1474 certificate.set_serial_number(2 ** 32 + 1)
1475 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1476 certificate.set_serial_number(2 ** 64 + 1)
1477 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001478 certificate.set_serial_number(2 ** 128 + 1)
1479 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1480
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001481 def _setBoundTest(self, which):
1482 """
Alex Gaynor31287502015-09-05 16:11:27 -04001483 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1484 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1485 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001486 """
1487 certificate = X509()
1488 set = getattr(certificate, 'set_not' + which)
1489 get = getattr(certificate, 'get_not' + which)
1490
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001491 # Starts with no value.
1492 self.assertEqual(get(), None)
1493
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001494 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001495 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001496 set(when)
1497 self.assertEqual(get(), when)
1498
1499 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001500 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001501 set(when)
1502 self.assertEqual(get(), when)
1503
1504 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001505 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001506 set(when)
1507 self.assertEqual(get(), when)
1508
1509 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001510 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001511
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001512 # The wrong number of arguments results in a TypeError.
1513 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001514 with pytest.raises(TypeError):
1515 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001516 self.assertRaises(TypeError, get, b("foo bar"))
1517
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001518 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001519
1520 def test_set_notBefore(self):
1521 """
Alex Gaynor31287502015-09-05 16:11:27 -04001522 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1523 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1524 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001525 """
1526 self._setBoundTest("Before")
1527
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001528 def test_set_notAfter(self):
1529 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001530 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001531 GENERALIZEDTIME and sets the end of the certificate's validity period
1532 to it.
1533 """
1534 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001535
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001536 def test_get_notBefore(self):
1537 """
Alex Gaynor31287502015-09-05 16:11:27 -04001538 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1539 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001540 internally.
1541 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001542 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001543 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001544
Rick Dean38a05c82009-07-18 01:41:30 -05001545 def test_get_notAfter(self):
1546 """
Alex Gaynor31287502015-09-05 16:11:27 -04001547 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1548 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001549 internally.
1550 """
1551 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001552 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001553
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001554 def test_gmtime_adj_notBefore_wrong_args(self):
1555 """
Alex Gaynor31287502015-09-05 16:11:27 -04001556 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1557 called with the wrong number of arguments or a non-:py:obj:`int`
1558 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001559 """
1560 cert = X509()
1561 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1562 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1563 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1564
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001565 def test_gmtime_adj_notBefore(self):
1566 """
Alex Gaynor31287502015-09-05 16:11:27 -04001567 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1568 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001569 """
1570 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001571 not_before_min = (
1572 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1573 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001574 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001575 not_before = datetime.strptime(
1576 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1577 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001578 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1579 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001580
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001581 def test_gmtime_adj_notAfter_wrong_args(self):
1582 """
Alex Gaynor31287502015-09-05 16:11:27 -04001583 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1584 called with the wrong number of arguments or a non-:py:obj:`int`
1585 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001586 """
1587 cert = X509()
1588 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1589 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1590 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1591
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001592 def test_gmtime_adj_notAfter(self):
1593 """
Alex Gaynor31287502015-09-05 16:11:27 -04001594 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1595 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001596 """
1597 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001598 not_after_min = (
1599 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1600 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001601 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001602 not_after = datetime.strptime(
1603 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1604 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001605 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1606 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001607
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001608 def test_has_expired_wrong_args(self):
1609 """
Alex Gaynor31287502015-09-05 16:11:27 -04001610 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1611 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001612 """
1613 cert = X509()
1614 self.assertRaises(TypeError, cert.has_expired, None)
1615
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001616 def test_has_expired(self):
1617 """
Alex Gaynor31287502015-09-05 16:11:27 -04001618 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1619 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001620 """
1621 cert = X509()
1622 cert.gmtime_adj_notAfter(-1)
1623 self.assertTrue(cert.has_expired())
1624
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001625 def test_has_not_expired(self):
1626 """
Alex Gaynor31287502015-09-05 16:11:27 -04001627 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1628 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001629 """
1630 cert = X509()
1631 cert.gmtime_adj_notAfter(2)
1632 self.assertFalse(cert.has_expired())
1633
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001634 def test_root_has_not_expired(self):
1635 """
Alex Gaynor31287502015-09-05 16:11:27 -04001636 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1637 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001638 """
1639 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1640 self.assertFalse(cert.has_expired())
1641
Rick Dean38a05c82009-07-18 01:41:30 -05001642 def test_digest(self):
1643 """
Alex Gaynor31287502015-09-05 16:11:27 -04001644 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1645 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001646 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001647 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001648 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001649 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1650 # actually matters to the assertion (ie, another arbitrary, good
1651 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001652 # Digest verified with the command:
1653 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001654 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001655 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001656
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001657 def _extcert(self, pkey, extensions):
1658 cert = X509()
1659 cert.set_pubkey(pkey)
1660 cert.get_subject().commonName = "Unit Tests"
1661 cert.get_issuer().commonName = "Unit Tests"
1662 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1663 cert.set_notBefore(when)
1664 cert.set_notAfter(when)
1665
1666 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001667 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001668 return load_certificate(
1669 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1670
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001671 def test_extension_count(self):
1672 """
Alex Gaynor31287502015-09-05 16:11:27 -04001673 :py:obj:`X509.get_extension_count` returns the number of extensions
1674 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001675 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001676 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001677 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1678 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001679 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001680 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001681
1682 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001683 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001684 self.assertEqual(c.get_extension_count(), 0)
1685
1686 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001687 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001688 self.assertEqual(c.get_extension_count(), 1)
1689
1690 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001691 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001692 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001693
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001694 def test_get_extension(self):
1695 """
Alex Gaynor31287502015-09-05 16:11:27 -04001696 :py:obj:`X509.get_extension` takes an integer and returns an
1697 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001698 """
1699 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001700 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1701 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001702 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001703 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001704
1705 cert = self._extcert(pkey, [ca, key, subjectAltName])
1706
1707 ext = cert.get_extension(0)
1708 self.assertTrue(isinstance(ext, X509Extension))
1709 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001710 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001711
1712 ext = cert.get_extension(1)
1713 self.assertTrue(isinstance(ext, X509Extension))
1714 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001715 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001716
1717 ext = cert.get_extension(2)
1718 self.assertTrue(isinstance(ext, X509Extension))
1719 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001720 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001721
1722 self.assertRaises(IndexError, cert.get_extension, -1)
1723 self.assertRaises(IndexError, cert.get_extension, 4)
1724 self.assertRaises(TypeError, cert.get_extension, "hello")
1725
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001726 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001727 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001728 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001729 bytes and this value is reflected in the string representation of the
1730 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001731 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001732 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001733
1734 ext = cert.get_extension(3)
1735 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001736 self.assertEqual(
1737 b("DNS:altnull.python.org\x00example.com, "
1738 "email:null@python.org\x00user@example.org, "
1739 "URI:http://null.python.org\x00http://example.org, "
1740 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1741 b(str(ext)))
1742
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001743 def test_invalid_digest_algorithm(self):
1744 """
Alex Gaynor31287502015-09-05 16:11:27 -04001745 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1746 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001747 """
1748 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001749 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001750
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001751 def test_get_subject_wrong_args(self):
1752 """
Alex Gaynor31287502015-09-05 16:11:27 -04001753 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1754 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001755 """
1756 cert = X509()
1757 self.assertRaises(TypeError, cert.get_subject, None)
1758
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001759 def test_get_subject(self):
1760 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001761 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001762 """
1763 cert = load_certificate(FILETYPE_PEM, self.pemData)
1764 subj = cert.get_subject()
1765 self.assertTrue(isinstance(subj, X509Name))
1766 self.assertEquals(
1767 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001768 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1769 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001770
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001771 def test_set_subject_wrong_args(self):
1772 """
Alex Gaynor31287502015-09-05 16:11:27 -04001773 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1774 the wrong number of arguments or an argument not of type
1775 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001776 """
1777 cert = X509()
1778 self.assertRaises(TypeError, cert.set_subject)
1779 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001780 with pytest.raises(TypeError):
1781 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001782
1783 def test_set_subject(self):
1784 """
Alex Gaynor31287502015-09-05 16:11:27 -04001785 :py:obj:`X509.set_subject` changes the subject of the certificate to
1786 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001787 """
1788 cert = X509()
1789 name = cert.get_subject()
1790 name.C = 'AU'
1791 name.O = 'Unit Tests'
1792 cert.set_subject(name)
1793 self.assertEquals(
1794 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001795 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001796
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001797 def test_get_issuer_wrong_args(self):
1798 """
Alex Gaynor31287502015-09-05 16:11:27 -04001799 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1800 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001801 """
1802 cert = X509()
1803 self.assertRaises(TypeError, cert.get_issuer, None)
1804
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001805 def test_get_issuer(self):
1806 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001807 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001808 """
1809 cert = load_certificate(FILETYPE_PEM, self.pemData)
1810 subj = cert.get_issuer()
1811 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001812 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001813 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001814 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001815 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1816 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001817
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001818 def test_set_issuer_wrong_args(self):
1819 """
Alex Gaynor31287502015-09-05 16:11:27 -04001820 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1821 the wrong number of arguments or an argument not of type
1822 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001823 """
1824 cert = X509()
1825 self.assertRaises(TypeError, cert.set_issuer)
1826 self.assertRaises(TypeError, cert.set_issuer, None)
1827 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1828
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001829 def test_set_issuer(self):
1830 """
Alex Gaynor31287502015-09-05 16:11:27 -04001831 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1832 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001833 """
1834 cert = X509()
1835 name = cert.get_issuer()
1836 name.C = 'AU'
1837 name.O = 'Unit Tests'
1838 cert.set_issuer(name)
1839 self.assertEquals(
1840 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001841 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001842
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001843 def test_get_pubkey_uninitialized(self):
1844 """
Alex Gaynor31287502015-09-05 16:11:27 -04001845 When called on a certificate with no public key,
1846 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001847 """
1848 cert = X509()
1849 self.assertRaises(Error, cert.get_pubkey)
1850
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001851 def test_subject_name_hash_wrong_args(self):
1852 """
Alex Gaynor31287502015-09-05 16:11:27 -04001853 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1854 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001855 """
1856 cert = X509()
1857 self.assertRaises(TypeError, cert.subject_name_hash, None)
1858
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001859 def test_subject_name_hash(self):
1860 """
Alex Gaynor31287502015-09-05 16:11:27 -04001861 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1862 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001863 """
1864 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001865 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001866 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001867 [3350047874, # OpenSSL 0.9.8, MD5
1868 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001869 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001870
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001871 def test_get_signature_algorithm(self):
1872 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001873 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001874 the algorithm used to sign the certificate.
1875 """
1876 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001877 self.assertEqual(
1878 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001879
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001880 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001881 """
Alex Gaynor31287502015-09-05 16:11:27 -04001882 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1883 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001884 """
1885 # This certificate has been modified to indicate a bogus OID in the
1886 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001887 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001888-----BEGIN CERTIFICATE-----
1889MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1890EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1891cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1892MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1893EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1894CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1895AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1896+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1897hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1898BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1899FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1900dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1901aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1902MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1903jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1904PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1905tgI5
1906-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001907""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001908 cert = load_certificate(FILETYPE_PEM, certPEM)
1909 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001910
1911
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001912class X509StoreTests(TestCase):
1913 """
1914 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1915 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001916
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001917 def test_type(self):
1918 """
1919 :py:obj:`X509StoreType` is a type object.
1920 """
1921 self.assertIdentical(X509Store, X509StoreType)
1922 self.assertConsistentType(X509Store, 'X509Store')
1923
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001924 def test_add_cert_wrong_args(self):
1925 store = X509Store()
1926 self.assertRaises(TypeError, store.add_cert)
1927 self.assertRaises(TypeError, store.add_cert, object())
1928 self.assertRaises(TypeError, store.add_cert, X509(), object())
1929
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001930 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001931 """
1932 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1933 certificate store.
1934 """
1935 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001936 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001937 store.add_cert(cert)
1938
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001939 def test_add_cert_rejects_duplicate(self):
1940 """
Alex Gaynor31287502015-09-05 16:11:27 -04001941 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1942 an attempt is made to add the same certificate to the store more than
1943 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001944 """
1945 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1946 store = X509Store()
1947 store.add_cert(cert)
1948 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001949
1950
Rick Dean623ee362009-07-17 12:22:16 -05001951class PKCS12Tests(TestCase):
1952 """
Alex Gaynor31287502015-09-05 16:11:27 -04001953 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1954 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001955 """
1956 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1957
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001958 def test_type(self):
1959 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001960 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001961 """
1962 self.assertIdentical(PKCS12, PKCS12Type)
1963 self.assertConsistentType(PKCS12, 'PKCS12')
1964
Rick Deanf94096c2009-07-18 14:23:06 -05001965 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001966 """
Alex Gaynor31287502015-09-05 16:11:27 -04001967 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1968 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001969 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001970 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001971 self.assertEqual(None, p12.get_certificate())
1972 self.assertEqual(None, p12.get_privatekey())
1973 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001974 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001975
1976 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001977 """
Alex Gaynor31287502015-09-05 16:11:27 -04001978 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1979 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1980 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1981 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001982 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001983 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001984 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001985 self.assertRaises(TypeError, p12.set_certificate, PKey())
1986 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001987 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001988 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1989 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001990 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1991 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1992 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001993 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001994 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1995 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001996
1997 def test_key_only(self):
1998 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001999 A :py:obj:`PKCS12` with only a private key can be exported using
2000 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002001 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002002 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002003 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002004 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002005 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05002006 self.assertEqual(None, p12.get_certificate())
2007 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002008 try:
2009 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2010 except Error:
2011 # Some versions of OpenSSL will throw an exception
2012 # for this nearly useless PKCS12 we tried to generate:
2013 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2014 return
Rick Dean623ee362009-07-17 12:22:16 -05002015 p12 = load_pkcs12(dumped_p12, passwd)
2016 self.assertEqual(None, p12.get_ca_certificates())
2017 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002018
2019 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2020 # future this will be improved.
2021 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05002022
2023 def test_cert_only(self):
2024 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002025 A :py:obj:`PKCS12` with only a certificate can be exported using
2026 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002027 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002028 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002029 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002030 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002031 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05002032 self.assertEqual(cert, p12.get_certificate())
2033 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002034 try:
2035 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2036 except Error:
2037 # Some versions of OpenSSL will throw an exception
2038 # for this nearly useless PKCS12 we tried to generate:
2039 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2040 return
Rick Dean623ee362009-07-17 12:22:16 -05002041 p12 = load_pkcs12(dumped_p12, passwd)
2042 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002043
2044 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
2045 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2046
2047 # Oh ho. It puts the certificate into the ca certificates list, in
2048 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2049 # that to check to see if it reconstructed the certificate we expected
2050 # it to. At some point, hopefully this will change so that
2051 # p12.get_certificate() is actually what returns the loaded
2052 # certificate.
2053 self.assertEqual(
2054 cleartextCertificatePEM,
2055 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002056
Alex Gaynor31287502015-09-05 16:11:27 -04002057 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2058 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002059 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002060 Generate a PKCS12 object with components from PEM. Verify that the set
2061 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002062 """
Rick Deanf94096c2009-07-18 14:23:06 -05002063 p12 = PKCS12()
2064 if cert_pem:
2065 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2066 self.assertEqual(ret, None)
2067 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002068 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002069 self.assertEqual(ret, None)
2070 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002071 ret = p12.set_ca_certificates(
2072 (load_certificate(FILETYPE_PEM, ca_pem),)
2073 )
Rick Deanf94096c2009-07-18 14:23:06 -05002074 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002075 if friendly_name:
2076 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002077 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002078 return p12
2079
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002080 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002081 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002082 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002083 Use openssl program to confirm three components are recoverable from a
2084 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002085 """
2086 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002087 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002088 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2089 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002090 self.assertEqual(recovered_key[-len(key):], key)
2091 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002092 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002093 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2094 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002095 self.assertEqual(recovered_cert[-len(cert):], cert)
2096 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002097 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002098 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2099 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002100 self.assertEqual(recovered_cert[-len(ca):], ca)
2101
Stephen Holsapple38482622014-04-05 20:29:34 -07002102 def verify_pkcs12_container(self, p12):
2103 """
2104 Verify that the PKCS#12 container contains the correct client
2105 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002106
2107 :param p12: The PKCS12 instance to verify.
2108 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002109 """
2110 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2111 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002112 self.assertEqual(
2113 (client_cert_pem, client_key_pem, None),
2114 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002115
Rick Deanf94096c2009-07-18 14:23:06 -05002116 def test_load_pkcs12(self):
2117 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002118 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002119 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002120 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002121 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002122 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002123 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002124 pem,
2125 b"pkcs12",
2126 b"-export",
2127 b"-clcerts",
2128 b"-passout",
2129 b"pass:" + passwd
2130 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002131 p12 = load_pkcs12(p12_str, passphrase=passwd)
2132 self.verify_pkcs12_container(p12)
2133
Abraham Martinc5484ba2015-03-25 15:33:05 +00002134 def test_load_pkcs12_text_passphrase(self):
2135 """
2136 A PKCS12 string generated using the openssl command line can be loaded
2137 with :py:obj:`load_pkcs12` and its components extracted and examined.
2138 Using text as passphrase instead of bytes. DeprecationWarning expected.
2139 """
2140 pem = client_key_pem + client_cert_pem
2141 passwd = b"whatever"
2142 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2143 b"-passout", b"pass:" + passwd)
2144 with catch_warnings(record=True) as w:
2145 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002146 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002147
2148 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002149 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002150 WARNING_TYPE_EXPECTED
2151 ),
2152 str(w[-1].message)
2153 )
2154 self.assertIs(w[-1].category, DeprecationWarning)
2155
Abraham Martinc5484ba2015-03-25 15:33:05 +00002156 self.verify_pkcs12_container(p12)
2157
Stephen Holsapple38482622014-04-05 20:29:34 -07002158 def test_load_pkcs12_no_passphrase(self):
2159 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002160 A PKCS12 string generated using openssl command line can be loaded with
2161 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2162 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002163 """
2164 pem = client_key_pem + client_cert_pem
2165 p12_str = _runopenssl(
2166 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2167 p12 = load_pkcs12(p12_str)
2168 self.verify_pkcs12_container(p12)
2169
Stephen Holsapple38482622014-04-05 20:29:34 -07002170 def _dump_and_load(self, dump_passphrase, load_passphrase):
2171 """
2172 A helper method to dump and load a PKCS12 object.
2173 """
2174 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2175 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2176 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2177
Stephen Holsapple38482622014-04-05 20:29:34 -07002178 def test_load_pkcs12_null_passphrase_load_empty(self):
2179 """
2180 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002181 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002182 extracted and examined.
2183 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002184 self.verify_pkcs12_container(
2185 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002186
Stephen Holsapple38482622014-04-05 20:29:34 -07002187 def test_load_pkcs12_null_passphrase_load_null(self):
2188 """
2189 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002190 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002191 extracted and examined.
2192 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002193 self.verify_pkcs12_container(
2194 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002195
Stephen Holsapple38482622014-04-05 20:29:34 -07002196 def test_load_pkcs12_empty_passphrase_load_empty(self):
2197 """
2198 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002199 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002200 extracted and examined.
2201 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002202 self.verify_pkcs12_container(
2203 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002204
Stephen Holsapple38482622014-04-05 20:29:34 -07002205 def test_load_pkcs12_empty_passphrase_load_null(self):
2206 """
2207 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002208 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002209 extracted and examined.
2210 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002211 self.verify_pkcs12_container(
2212 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002213
Rick Deanee568302009-07-24 09:56:29 -05002214 def test_load_pkcs12_garbage(self):
2215 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002216 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2217 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002218 """
2219 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002220 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002221 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2222 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002223
Rick Deanf94096c2009-07-18 14:23:06 -05002224 def test_replace(self):
2225 """
Alex Gaynor31287502015-09-05 16:11:27 -04002226 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2227 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002228 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002229 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002230 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2231 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2232 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002233 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002234 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002235 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002236 self.assertEqual(1, len(p12.get_ca_certificates()))
2237 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002238 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002239 self.assertEqual(2, len(p12.get_ca_certificates()))
2240 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2241 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2242
Rick Deanf94096c2009-07-18 14:23:06 -05002243 def test_friendly_name(self):
2244 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002245 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002246 :py:obj:`PKCS12.get_friendlyname` and
2247 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2248 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002249 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002250 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002251 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002252 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002253 p12.set_friendlyname(friendly_name)
2254 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002255 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002256 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002257 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002258 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002259 # We would use the openssl program to confirm the friendly
2260 # name, but it is not possible. The pkcs12 command
2261 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002262 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002263 self.check_recovery(
2264 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2265 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002266
Rick Deanf94096c2009-07-18 14:23:06 -05002267 def test_various_empty_passphrases(self):
2268 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002269 Test that missing, None, and '' passphrases are identical for PKCS12
2270 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002271 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002272 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002273 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002274 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2275 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2276 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2277 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2278 self.check_recovery(
2279 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2280 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002281
Rick Deanf94096c2009-07-18 14:23:06 -05002282 def test_removing_ca_cert(self):
2283 """
Alex Gaynor31287502015-09-05 16:11:27 -04002284 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2285 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002286 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002287 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2288 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002289 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002290
Rick Deanf94096c2009-07-18 14:23:06 -05002291 def test_export_without_mac(self):
2292 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002293 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002294 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002295 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002296 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002297 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002298 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002299 self.check_recovery(
2300 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002301 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002302
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002303 def test_load_without_mac(self):
2304 """
2305 Loading a PKCS12 without a MAC does something other than crash.
2306 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002307 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002308 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2309 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002310 try:
2311 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2312 # The person who generated this PCKS12 should be flogged,
2313 # or better yet we should have a means to determine
2314 # whether a PCKS12 had a MAC that was verified.
2315 # Anyway, libopenssl chooses to allow it, so the
2316 # pyopenssl binding does as well.
2317 self.assertTrue(isinstance(recovered_p12, PKCS12))
2318 except Error:
2319 # Failing here with an exception is preferred as some openssl
2320 # versions do.
2321 pass
Rick Dean623ee362009-07-17 12:22:16 -05002322
Rick Dean25bcc1f2009-07-20 11:53:13 -05002323 def test_zero_len_list_for_ca(self):
2324 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002325 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002326 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002327 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002328 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002329 p12.set_ca_certificates([])
2330 self.assertEqual((), p12.get_ca_certificates())
2331 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2332 self.check_recovery(
2333 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2334 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002335
Rick Deanf94096c2009-07-18 14:23:06 -05002336 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002337 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002338 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002339 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002340 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002341 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002342 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002343 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002344
Abraham Martinc5484ba2015-03-25 15:33:05 +00002345 def test_export_without_bytes(self):
2346 """
2347 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2348 """
2349 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2350
2351 with catch_warnings(record=True) as w:
2352 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002353 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002354 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002355 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002356 WARNING_TYPE_EXPECTED
2357 ),
2358 str(w[-1].message)
2359 )
2360 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002361 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002362 dumped_p12,
2363 key=server_key_pem,
2364 cert=server_cert_pem,
2365 passwd=b"randomtext"
2366 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002367
Rick Deanf94096c2009-07-18 14:23:06 -05002368 def test_key_cert_mismatch(self):
2369 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002370 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002371 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002372 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002373 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2374 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002375
2376
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002377# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002378_cmdLineQuoteRe = re.compile(br'(\\*)"')
2379_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002380
2381
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002382def cmdLineQuote(s):
2383 """
2384 Internal method for quoting a single command-line argument.
2385
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002386 See http://www.perlmonks.org/?node_id=764004
2387
Jonathan Ballet648875f2011-07-16 14:14:58 +09002388 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002389 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002390 cmd.exe-style quoting
2391
Jonathan Ballet648875f2011-07-16 14:14:58 +09002392 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002393 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002394 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002395 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2396 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002397
2398
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002399def quoteArguments(arguments):
2400 """
2401 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002402 a similar API. This allows the list passed to
2403 :py:obj:`reactor.spawnProcess` to match the child process's
2404 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002405
Jonathan Ballet648875f2011-07-16 14:14:58 +09002406 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002407 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002408
Jonathan Ballet648875f2011-07-16 14:14:58 +09002409 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002410 :return: A space-delimited string containing quoted versions of
2411 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002412 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002413 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002414
2415
Rick Dean4c9ad612009-07-17 15:05:22 -05002416def _runopenssl(pem, *args):
2417 """
2418 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002419 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002420 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002421 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002422 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002423 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2424 for arg in args
2425 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002426 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002427 command = b"openssl " + quoteArguments(args)
2428 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002429 proc.stdin.write(pem)
2430 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002431 output = proc.stdout.read()
2432 proc.stdout.close()
2433 proc.wait()
2434 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002435
2436
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002437class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002438 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002439 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002440 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002441 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002442 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002443 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002444 """
2445 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002446
2447 assert True is key._only_public
2448 assert 2048 == key.bits()
2449 assert TYPE_RSA == key.type()
2450
2451 def test_invalid_type(self):
2452 """
2453 load_publickey doesn't support FILETYPE_TEXT.
2454 """
2455 with pytest.raises(ValueError):
2456 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2457
2458 def test_invalid_key_format(self):
2459 """
2460 load_publickey explodes on incorrect keys.
2461 """
2462 with pytest.raises(Error):
2463 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2464
2465 def test_tolerates_unicode_strings(self):
2466 """
2467 load_publickey works with text strings, not just bytes.
2468 """
2469 serialized = cleartextPublicKeyPEM.decode('ascii')
2470 key = load_publickey(FILETYPE_PEM, serialized)
2471 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2472
2473 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002474
2475
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002476class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002477 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002478 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002479
2480 Add new tests to `TestFunctions` above.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002481 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002482
2483 def test_load_privatekey_invalid_format(self):
2484 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002485 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2486 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002487 """
2488 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2489
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002490 def test_load_privatekey_invalid_passphrase_type(self):
2491 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002492 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2493 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002494 """
2495 self.assertRaises(
2496 TypeError,
2497 load_privatekey,
2498 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2499
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002500 def test_load_privatekey_wrong_args(self):
2501 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002502 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2503 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002504 """
2505 self.assertRaises(TypeError, load_privatekey)
2506
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002507 def test_load_privatekey_wrongPassphrase(self):
2508 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002509 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2510 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002511 """
2512 self.assertRaises(
2513 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002514 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002515
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002516 def test_load_privatekey_passphraseWrongType(self):
2517 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002518 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2519 a passphrase with a private key encoded in a format, that doesn't
2520 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002521 """
2522 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2523 blob = dump_privatekey(FILETYPE_ASN1, key)
2524 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002525 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002526
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002527 def test_load_privatekey_passphrase(self):
2528 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002529 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2530 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002531 """
2532 key = load_privatekey(
2533 FILETYPE_PEM, encryptedPrivateKeyPEM,
2534 encryptedPrivateKeyPEMPassphrase)
2535 self.assertTrue(isinstance(key, PKeyType))
2536
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002537 def test_load_privatekey_passphrase_exception(self):
2538 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002539 If the passphrase callback raises an exception, that exception is
2540 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002541 """
2542 def cb(ignored):
2543 raise ArithmeticError
2544
Alex Gaynor791212d2015-09-05 15:46:08 -04002545 with pytest.raises(ArithmeticError):
2546 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002547
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002548 def test_load_privatekey_wrongPassphraseCallback(self):
2549 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002550 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2551 is passed an encrypted PEM and a passphrase callback which returns an
2552 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002553 """
2554 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002555
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002556 def cb(*a):
2557 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002558 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002559 self.assertRaises(
2560 Error,
2561 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2562 self.assertTrue(called)
2563
2564 def test_load_privatekey_passphraseCallback(self):
2565 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002566 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2567 encrypted PEM string if given a passphrase callback which returns the
2568 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002569 """
2570 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002571
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002572 def cb(writing):
2573 called.append(writing)
2574 return encryptedPrivateKeyPEMPassphrase
2575 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2576 self.assertTrue(isinstance(key, PKeyType))
2577 self.assertEqual(called, [False])
2578
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002579 def test_load_privatekey_passphrase_wrong_return_type(self):
2580 """
2581 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2582 callback returns something other than a byte string.
2583 """
2584 self.assertRaises(
2585 ValueError,
2586 load_privatekey,
2587 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2588
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002589 def test_dump_privatekey_wrong_args(self):
2590 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002591 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2592 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002593 """
2594 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002595 # If cipher name is given, password is required.
2596 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002597 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002598
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002599 def test_dump_privatekey_unknown_cipher(self):
2600 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002601 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2602 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002603 """
2604 key = PKey()
2605 key.generate_key(TYPE_RSA, 512)
2606 self.assertRaises(
2607 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002608 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002609
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002610 def test_dump_privatekey_invalid_passphrase_type(self):
2611 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002612 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2613 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002614 """
2615 key = PKey()
2616 key.generate_key(TYPE_RSA, 512)
2617 self.assertRaises(
2618 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002619 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002620
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002621 def test_dump_privatekey_invalid_filetype(self):
2622 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002623 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2624 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002625 """
2626 key = PKey()
2627 key.generate_key(TYPE_RSA, 512)
2628 self.assertRaises(ValueError, dump_privatekey, 100, key)
2629
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002630 def test_load_privatekey_passphraseCallbackLength(self):
2631 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002632 :py:obj:`crypto.load_privatekey` should raise an error when the
2633 passphrase provided by the callback is too long, not silently truncate
2634 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002635 """
2636 def cb(ignored):
2637 return "a" * 1025
2638
Alex Gaynor791212d2015-09-05 15:46:08 -04002639 with pytest.raises(ValueError):
2640 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002641
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002642 def test_dump_privatekey_passphrase(self):
2643 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002644 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2645 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002646 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002647 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002648 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002649 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2650 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002651 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2652 self.assertTrue(isinstance(loadedKey, PKeyType))
2653 self.assertEqual(loadedKey.type(), key.type())
2654 self.assertEqual(loadedKey.bits(), key.bits())
2655
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002656 def test_dump_privatekey_passphraseWrongType(self):
2657 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002658 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2659 a passphrase with a private key encoded in a format, that doesn't
2660 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002661 """
2662 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002663 with pytest.raises(ValueError):
2664 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002665
Rick Dean5b7b6372009-04-01 11:34:06 -05002666 def test_dump_certificate(self):
2667 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002668 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002669 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002670 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002671 cert = load_certificate(FILETYPE_PEM, pemData)
2672 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2673 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2674 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002675 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002676 self.assertEqual(dumped_der, good_der)
2677 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2678 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2679 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2680 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002681 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002682 self.assertEqual(dumped_text, good_text)
2683
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002684 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002685 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002686 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002687 """
2688 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002689 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002690 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2691 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002692
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002693 def test_dump_privatekey_asn1(self):
2694 """
2695 :py:obj:`dump_privatekey` writes a DER
2696 """
2697 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2698 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2699
Rick Dean5b7b6372009-04-01 11:34:06 -05002700 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002701 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002702 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002703 self.assertEqual(dumped_der, good_der)
2704 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2705 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2706 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002707
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002708 def test_dump_privatekey_text(self):
2709 """
2710 :py:obj:`dump_privatekey` writes a text
2711 """
2712 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2713 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2714
Rick Dean5b7b6372009-04-01 11:34:06 -05002715 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002716 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002717 self.assertEqual(dumped_text, good_text)
2718
Cory Benfield6492f7c2015-10-27 16:57:58 +09002719 def test_dump_publickey_pem(self):
2720 """
Cory Benfield11c10192015-10-27 17:23:03 +09002721 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002722 """
2723 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2724 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002725 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002726
2727 def test_dump_publickey_asn1(self):
2728 """
Cory Benfield11c10192015-10-27 17:23:03 +09002729 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002730 """
2731 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2732 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2733 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2734 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002735 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002736
Cory Benfielde02c7d82015-10-27 17:34:49 +09002737 def test_dump_publickey_invalid_type(self):
2738 """
2739 dump_publickey doesn't support FILETYPE_TEXT.
2740 """
2741 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2742
2743 with pytest.raises(ValueError):
2744 dump_publickey(FILETYPE_TEXT, key)
2745
Rick Dean5b7b6372009-04-01 11:34:06 -05002746 def test_dump_certificate_request(self):
2747 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002748 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002749 """
Alex Gaynor31287502015-09-05 16:11:27 -04002750 req = load_certificate_request(
2751 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002752 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2753 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2754 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002755 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002756 self.assertEqual(dumped_der, good_der)
2757 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2758 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2759 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2760 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002761 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002762 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002763 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002764
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002765 def test_dump_privatekey_passphraseCallback(self):
2766 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002767 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2768 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002769 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002770 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002771 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002772
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002773 def cb(writing):
2774 called.append(writing)
2775 return passphrase
2776 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002777 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2778 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002779 self.assertEqual(called, [True])
2780 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2781 self.assertTrue(isinstance(loadedKey, PKeyType))
2782 self.assertEqual(loadedKey.type(), key.type())
2783 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002784
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002785 def test_dump_privatekey_passphrase_exception(self):
2786 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002787 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002788 by the passphrase callback.
2789 """
2790 def cb(ignored):
2791 raise ArithmeticError
2792
2793 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002794 with pytest.raises(ArithmeticError):
2795 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002796
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002797 def test_dump_privatekey_passphraseCallbackLength(self):
2798 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002799 :py:obj:`crypto.dump_privatekey` should raise an error when the
2800 passphrase provided by the callback is too long, not silently truncate
2801 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002802 """
2803 def cb(ignored):
2804 return "a" * 1025
2805
2806 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002807 with pytest.raises(ValueError):
2808 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002809
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002810 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002811 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002812 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2813 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002814 """
2815 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2816 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2817
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002818 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002819 """
2820 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2821 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2822 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002823 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2824 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2825
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002826 def test_load_pkcs7_data_invalid(self):
2827 """
2828 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2829 :py:obj:`Error` is raised.
2830 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002831 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002832
Alex Gaynor09a386e2016-07-03 09:32:44 -04002833 def test_load_pkcs7_type_invalid(self):
2834 """
2835 If the type passed to :obj:`load_pkcs7_data`, :obj:`ValueError` is
2836 raised.
2837 """
2838 with pytest.raises(ValueError):
2839 load_pkcs7_data(object(), b"foo")
2840
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002841
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002842class LoadCertificateTests(TestCase):
2843 """
2844 Tests for :py:obj:`load_certificate_request`.
2845 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002846
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002847 def test_badFileType(self):
2848 """
2849 If the file type passed to :py:obj:`load_certificate_request` is
2850 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2851 :py:class:`ValueError` is raised.
2852 """
2853 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2854
2855
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002856class PKCS7Tests(TestCase):
2857 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002858 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002859 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002860
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002861 def test_type(self):
2862 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002863 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002864 """
2865 self.assertTrue(isinstance(PKCS7Type, type))
2866 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2867
2868 # XXX This doesn't currently work.
2869 # self.assertIdentical(PKCS7, PKCS7Type)
2870
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002871 # XXX Opposite results for all these following methods
2872
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002873 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002874 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002875 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2876 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002877 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002878 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2879 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2880
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002881 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002882 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002883 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2884 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002885 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002886 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2887 self.assertTrue(pkcs7.type_is_signed())
2888
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002889 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002890 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002891 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2892 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002893 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002894 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2895 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2896
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002897 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002898 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002899 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2900 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002901 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002902 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2903 self.assertFalse(pkcs7.type_is_enveloped())
2904
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002905 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002906 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002907 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2908 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002909 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002910 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2911 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2912
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002913 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002914 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002915 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2916 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002917 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002918 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2919 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2920
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002921 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002922 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002923 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2924 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002925 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002926 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2927 self.assertFalse(pkcs7.type_is_data())
2928
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002929 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002930 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002931 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2932 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002933 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002934 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2935 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2936
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002937 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002938 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002939 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2940 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002941 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002942 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2943 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2944
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002945 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002946 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002947 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2948 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002949 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002950 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002951 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002952
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002953 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002954 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002955 If an attribute other than one of the methods tested here is accessed
2956 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2957 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002958 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002959 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2960 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2961
2962
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002963class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002964 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002965 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002966 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002967
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002968 def signable(self):
2969 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002970 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002971 """
2972 return NetscapeSPKI()
2973
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002974 def test_type(self):
2975 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002976 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2977 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002978 """
2979 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2980 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2981
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002982 def test_construction(self):
2983 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002984 :py:obj:`NetscapeSPKI` returns an instance of
2985 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002986 """
2987 nspki = NetscapeSPKI()
2988 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2989
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002990 def test_invalid_attribute(self):
2991 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002992 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2993 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002994 """
2995 nspki = NetscapeSPKI()
2996 self.assertRaises(AttributeError, lambda: nspki.foo)
2997
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002998 def test_b64_encode(self):
2999 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003000 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
3001 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003002 """
3003 nspki = NetscapeSPKI()
3004 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003005 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003006
3007
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003008class TestRevoked(object):
3009 """
3010 Please add test cases for the Revoked class here if possible. This class
3011 holds the new py.test style tests.
3012 """
3013 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3014 """
3015 The get_reason method on the Revoked class checks to see if the
3016 extension is NID_crl_reason and should skip it otherwise. This test
3017 loads a CRL with extensions it should ignore.
3018 """
3019 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3020 revoked = crl.get_revoked()
3021 reason = revoked[1].get_reason()
3022 assert reason == b'Unspecified'
3023
3024 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3025 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3026 revoked = crl.get_revoked()
3027 revoked[1].set_reason(None)
3028 reason = revoked[1].get_reason()
3029 assert reason is None
3030
3031
Rick Dean536ba022009-07-24 23:57:27 -05003032class RevokedTests(TestCase):
3033 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003034 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3035 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003036 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003037
Rick Dean536ba022009-07-24 23:57:27 -05003038 def test_construction(self):
3039 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003040 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003041 that it is empty.
3042 """
3043 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003044 self.assertTrue(isinstance(revoked, Revoked))
3045 self.assertEquals(type(revoked), Revoked)
3046 self.assertEquals(revoked.get_serial(), b('00'))
3047 self.assertEquals(revoked.get_rev_date(), None)
3048 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003049
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003050 def test_construction_wrong_args(self):
3051 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003052 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3053 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003054 """
3055 self.assertRaises(TypeError, Revoked, None)
3056 self.assertRaises(TypeError, Revoked, 1)
3057 self.assertRaises(TypeError, Revoked, "foo")
3058
Rick Dean536ba022009-07-24 23:57:27 -05003059 def test_serial(self):
3060 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003061 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003062 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003063 with grace.
3064 """
3065 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003066 ret = revoked.set_serial(b('10b'))
3067 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003068 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003069 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003070
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003071 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003072 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003073 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003074
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003075 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003076 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003077 self.assertRaises(TypeError, revoked.get_serial, 1)
3078 self.assertRaises(TypeError, revoked.get_serial, None)
3079 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003080
Rick Dean536ba022009-07-24 23:57:27 -05003081 def test_date(self):
3082 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003083 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003084 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003085 with grace.
3086 """
3087 revoked = Revoked()
3088 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003089 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003090
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003091 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003092 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003093 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003094 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003095 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003096
Rick Dean6385faf2009-07-26 00:07:47 -05003097 def test_reason(self):
3098 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003099 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003100 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003101 as "set". Likewise, each reason of all_reasons() must work.
3102 """
3103 revoked = Revoked()
3104 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003105 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003106 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003107 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003108 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003109 self.assertEquals(
3110 reason.lower().replace(b(' '), b('')),
3111 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003112 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003113
3114 revoked.set_reason(None)
3115 self.assertEqual(revoked.get_reason(), None)
3116
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003117 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003118 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003119 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003120 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003121 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003122 """
3123 revoked = Revoked()
3124 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003125 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003126
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003127 def test_get_reason_wrong_arguments(self):
3128 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003129 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3130 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003131 """
3132 revoked = Revoked()
3133 self.assertRaises(TypeError, revoked.get_reason, None)
3134 self.assertRaises(TypeError, revoked.get_reason, 1)
3135 self.assertRaises(TypeError, revoked.get_reason, "foo")
3136
3137
Rick Dean536ba022009-07-24 23:57:27 -05003138class CRLTests(TestCase):
3139 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003140 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003141 """
3142 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3143 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3144
Dan Sully44e767a2016-06-04 18:05:27 -07003145 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3146 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3147 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3148 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3149 intermediate_server_cert = load_certificate(
3150 FILETYPE_PEM, intermediate_server_cert_pem)
3151 intermediate_server_key = load_privatekey(
3152 FILETYPE_PEM, intermediate_server_key_pem)
3153
Rick Dean536ba022009-07-24 23:57:27 -05003154 def test_construction(self):
3155 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003156 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003157 that it is empty
3158 """
3159 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003160 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003161 self.assertEqual(crl.get_revoked(), None)
3162
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003163 def test_construction_wrong_args(self):
3164 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003165 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3166 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003167 """
3168 self.assertRaises(TypeError, CRL, 1)
3169 self.assertRaises(TypeError, CRL, "")
3170 self.assertRaises(TypeError, CRL, None)
3171
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003172 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003173 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003174 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003175 """
3176 crl = CRL()
3177 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003178 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003179 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003180 revoked.set_serial(b('3ab'))
3181 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003182 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003183 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003184
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003185 def test_export_pem(self):
3186 """
3187 If not passed a format, ``CRL.export`` returns a "PEM" format string
3188 representing a serial number, a revoked reason, and certificate issuer
3189 information.
3190 """
3191 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003192 # PEM format
3193 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003194 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003195
3196 # These magic values are based on the way the CRL above was constructed
3197 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003198 text.index(b('Serial Number: 03AB'))
3199 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003200 text.index(
3201 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3202 )
3203
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003204 def test_export_der(self):
3205 """
3206 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3207 "DER" format string representing a serial number, a revoked reason, and
3208 certificate issuer information.
3209 """
3210 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003211
3212 # DER format
3213 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003214 text = _runopenssl(
3215 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3216 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003217 text.index(b('Serial Number: 03AB'))
3218 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003219 text.index(
3220 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3221 )
3222
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003223 def test_export_text(self):
3224 """
3225 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3226 text format string like the one produced by the openssl command line
3227 tool.
3228 """
3229 crl = self._get_crl()
3230
3231 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3232 text = _runopenssl(
3233 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3234 )
Rick Dean536ba022009-07-24 23:57:27 -05003235
3236 # text format
3237 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3238 self.assertEqual(text, dumped_text)
3239
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003240 def test_export_custom_digest(self):
3241 """
3242 If passed the name of a digest function, ``CRL.export`` uses a
3243 signature algorithm based on that digest function.
3244 """
3245 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003246 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003247 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3248 text.index(b('Signature Algorithm: sha1'))
3249
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003250 def test_export_md5_digest(self):
3251 """
3252 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3253 not emit a deprecation warning.
3254 """
3255 crl = self._get_crl()
3256 with catch_warnings(record=True) as catcher:
3257 simplefilter("always")
3258 self.assertEqual(0, len(catcher))
3259 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3260 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3261 text.index(b('Signature Algorithm: md5'))
3262
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003263 def test_export_default_digest(self):
3264 """
3265 If not passed the name of a digest function, ``CRL.export`` uses a
3266 signature algorithm based on MD5 and emits a deprecation warning.
3267 """
3268 crl = self._get_crl()
3269 with catch_warnings(record=True) as catcher:
3270 simplefilter("always")
3271 dumped_crl = crl.export(self.cert, self.pkey)
3272 self.assertEqual(
3273 "The default message digest (md5) is deprecated. "
3274 "Pass the name of a message digest explicitly.",
3275 str(catcher[0].message),
3276 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003277 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3278 text.index(b('Signature Algorithm: md5'))
3279
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003280 def test_export_invalid(self):
3281 """
3282 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003283 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003284 """
3285 crl = CRL()
3286 self.assertRaises(Error, crl.export, X509(), PKey())
3287
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003288 def test_add_revoked_keyword(self):
3289 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003290 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003291 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003292 """
3293 crl = CRL()
3294 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003295 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003296 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003297 crl.add_revoked(revoked=revoked)
3298 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3299
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003300 def test_export_wrong_args(self):
3301 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003302 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003303 four arguments, or with arguments other than the certificate,
3304 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003305 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003306 """
3307 crl = CRL()
3308 self.assertRaises(TypeError, crl.export)
3309 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003310 with pytest.raises(TypeError):
3311 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3312 with pytest.raises(TypeError):
3313 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3314 with pytest.raises(TypeError):
3315 crl.export(self.cert, None, FILETYPE_PEM, 10)
3316 with pytest.raises(TypeError):
3317 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003318 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3319
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003320 def test_export_unknown_filetype(self):
3321 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003322 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003323 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3324 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003325 """
3326 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003327 with pytest.raises(ValueError):
3328 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003329
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003330 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003331 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003332 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003333 in a :py:obj:`ValueError` being raised.
3334 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003335 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003336 self.assertRaises(
3337 ValueError,
3338 crl.export,
3339 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3340 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003341
Rick Dean536ba022009-07-24 23:57:27 -05003342 def test_get_revoked(self):
3343 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003344 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003345 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3346 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003347 """
3348 crl = CRL()
3349
3350 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003351 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003352 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003353 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003354 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003355 revoked.set_serial(b('100'))
3356 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003357 crl.add_revoked(revoked)
3358
3359 revs = crl.get_revoked()
3360 self.assertEqual(len(revs), 2)
3361 self.assertEqual(type(revs[0]), Revoked)
3362 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003363 self.assertEqual(revs[0].get_serial(), b('03AB'))
3364 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003365 self.assertEqual(revs[0].get_rev_date(), now)
3366 self.assertEqual(revs[1].get_rev_date(), now)
3367
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003368 def test_get_revoked_wrong_args(self):
3369 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003370 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3371 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003372 """
3373 crl = CRL()
3374 self.assertRaises(TypeError, crl.get_revoked, None)
3375 self.assertRaises(TypeError, crl.get_revoked, 1)
3376 self.assertRaises(TypeError, crl.get_revoked, "")
3377 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3378
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003379 def test_add_revoked_wrong_args(self):
3380 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003381 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3382 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003383 """
3384 crl = CRL()
3385 self.assertRaises(TypeError, crl.add_revoked)
3386 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3387 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3388
Rick Dean536ba022009-07-24 23:57:27 -05003389 def test_load_crl(self):
3390 """
3391 Load a known CRL and inspect its revocations. Both
3392 PEM and DER formats are loaded.
3393 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003394 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003395 revs = crl.get_revoked()
3396 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003397 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003398 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003399 self.assertEqual(revs[1].get_serial(), b('0100'))
3400 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003401
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003402 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003403 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003404 revs = crl.get_revoked()
3405 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003406 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003407 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003408 self.assertEqual(revs[1].get_serial(), b('0100'))
3409 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003410
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003411 def test_load_crl_wrong_args(self):
3412 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003413 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3414 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003415 """
3416 self.assertRaises(TypeError, load_crl)
3417 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3418 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3419
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003420 def test_load_crl_bad_filetype(self):
3421 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003422 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3423 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003424 """
3425 self.assertRaises(ValueError, load_crl, 100, crlData)
3426
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003427 def test_load_crl_bad_data(self):
3428 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003429 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3430 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003431 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003432 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003433
Dan Sully44e767a2016-06-04 18:05:27 -07003434 def test_get_issuer(self):
3435 """
3436 Load a known CRL and assert its issuer's common name is
3437 what we expect from the encoded crlData string.
3438 """
3439 crl = load_crl(FILETYPE_PEM, crlData)
3440 self.assertTrue(isinstance(crl.get_issuer(), X509Name))
3441 self.assertEqual(crl.get_issuer().CN, 'Testing Root CA')
3442
Dominic Chenf05b2122015-10-13 16:32:35 +00003443 def test_dump_crl(self):
3444 """
3445 The dumped CRL matches the original input.
3446 """
3447 crl = load_crl(FILETYPE_PEM, crlData)
3448 buf = dump_crl(FILETYPE_PEM, crl)
3449 assert buf == crlData
3450
Dan Sully44e767a2016-06-04 18:05:27 -07003451 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3452 """
3453 Create a CRL.
3454
3455 :param list[X509] certs: A list of certificates to revoke.
3456 :rtype: CRL
3457 """
3458 crl = CRL()
3459 for cert in certs:
3460 revoked = Revoked()
3461 # FIXME: This string splicing is an unfortunate implementation
3462 # detail that has been reported in
3463 # https://github.com/pyca/pyopenssl/issues/258
3464 serial = hex(cert.get_serial_number())[2:].encode('utf-8')
3465 revoked.set_serial(serial)
3466 revoked.set_reason(b'unspecified')
3467 revoked.set_rev_date(b'20140601000000Z')
3468 crl.add_revoked(revoked)
3469 crl.set_version(1)
3470 crl.set_lastUpdate(b'20140601000000Z')
3471 crl.set_nextUpdate(b'20180601000000Z')
3472 crl.sign(issuer_cert, issuer_key, digest=b'sha512')
3473 return crl
3474
3475 def test_verify_with_revoked(self):
3476 """
3477 :func:`verify_certificate` raises error when an intermediate
3478 certificate is revoked.
3479 """
3480 store = X509Store()
3481 store.add_cert(self.root_cert)
3482 store.add_cert(self.intermediate_cert)
3483 root_crl = self._make_test_crl(
3484 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3485 intermediate_crl = self._make_test_crl(
3486 self.intermediate_cert, self.intermediate_key, certs=[])
3487 store.add_crl(root_crl)
3488 store.add_crl(intermediate_crl)
3489 store.set_flags(
3490 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3491 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3492 e = self.assertRaises(
3493 X509StoreContextError, store_ctx.verify_certificate)
3494 self.assertEqual(e.args[0][2], 'certificate revoked')
3495
3496 def test_verify_with_missing_crl(self):
3497 """
3498 :func:`verify_certificate` raises error when an intermediate
3499 certificate's CRL is missing.
3500 """
3501 store = X509Store()
3502 store.add_cert(self.root_cert)
3503 store.add_cert(self.intermediate_cert)
3504 root_crl = self._make_test_crl(
3505 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3506 store.add_crl(root_crl)
3507 store.set_flags(
3508 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3509 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3510 e = self.assertRaises(
3511 X509StoreContextError, store_ctx.verify_certificate)
3512 self.assertEqual(e.args[0][2], 'unable to get certificate CRL')
3513 self.assertEqual(
3514 e.certificate.get_subject().CN, 'intermediate-service')
3515
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003516
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003517class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003518 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003519 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003520 """
3521 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3522 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003523 intermediate_server_cert = load_certificate(
3524 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003525
3526 def test_valid(self):
3527 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003528 :py:obj:`verify_certificate` returns ``None`` when called with a
3529 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003530 """
3531 store = X509Store()
3532 store.add_cert(self.root_cert)
3533 store.add_cert(self.intermediate_cert)
3534 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003535 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003536
3537 def test_reuse(self):
3538 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003539 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003540 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003541 """
3542 store = X509Store()
3543 store.add_cert(self.root_cert)
3544 store.add_cert(self.intermediate_cert)
3545 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003546 self.assertEqual(store_ctx.verify_certificate(), None)
3547 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003548
3549 def test_trusted_self_signed(self):
3550 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003551 :py:obj:`verify_certificate` returns ``None`` when called with a
3552 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003553 """
3554 store = X509Store()
3555 store.add_cert(self.root_cert)
3556 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003557 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003558
3559 def test_untrusted_self_signed(self):
3560 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003561 :py:obj:`verify_certificate` raises error when a self-signed
3562 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003563 """
3564 store = X509Store()
3565 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003566 with pytest.raises(X509StoreContextError) as exc:
3567 store_ctx.verify_certificate()
3568
3569 assert exc.value.args[0][2] == 'self signed certificate'
3570 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003571
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003572 def test_invalid_chain_no_root(self):
3573 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003574 :py:obj:`verify_certificate` raises error when a root certificate is
3575 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003576 """
3577 store = X509Store()
3578 store.add_cert(self.intermediate_cert)
3579 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003580
3581 with pytest.raises(X509StoreContextError) as exc:
3582 store_ctx.verify_certificate()
3583
3584 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3585 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003586
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003587 def test_invalid_chain_no_intermediate(self):
3588 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003589 :py:obj:`verify_certificate` raises error when an intermediate
3590 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003591 """
3592 store = X509Store()
3593 store.add_cert(self.root_cert)
3594 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003595
Alex Gaynor85b49702015-09-05 16:30:59 -04003596 with pytest.raises(X509StoreContextError) as exc:
3597 store_ctx.verify_certificate()
3598
3599 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3600 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003601
Stephen Holsapple46a09252015-02-12 14:45:43 -08003602 def test_modification_pre_verify(self):
3603 """
3604 :py:obj:`verify_certificate` can use a store context modified after
3605 instantiation.
3606 """
3607 store_bad = X509Store()
3608 store_bad.add_cert(self.intermediate_cert)
3609 store_good = X509Store()
3610 store_good.add_cert(self.root_cert)
3611 store_good.add_cert(self.intermediate_cert)
3612 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003613
3614 with pytest.raises(X509StoreContextError) as exc:
3615 store_ctx.verify_certificate()
3616
3617 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3618 assert exc.value.certificate.get_subject().CN == 'intermediate'
3619
Stephen Holsapple46a09252015-02-12 14:45:43 -08003620 store_ctx.set_store(store_good)
3621 self.assertEqual(store_ctx.verify_certificate(), None)
3622
3623
James Yonan7c2e5d32010-02-27 05:45:50 -07003624class SignVerifyTests(TestCase):
3625 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003626 Tests for :py:obj:`OpenSSL.crypto.sign` and
3627 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003628 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003629
James Yonan7c2e5d32010-02-27 05:45:50 -07003630 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003631 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003632 :py:obj:`sign` generates a cryptographic signature which
3633 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003634 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003635 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003636 "It was a bright cold day in April, and the clocks were striking "
3637 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3638 "effort to escape the vile wind, slipped quickly through the "
3639 "glass doors of Victory Mansions, though not quickly enough to "
3640 "prevent a swirl of gritty dust from entering along with him.")
3641
3642 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003643 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003644 # verify the content with this cert
3645 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3646 # certificate unrelated to priv_key, used to trigger an error
3647 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003648
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003649 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003650 sig = sign(priv_key, content, digest)
3651
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003652 # Verify the signature of content, will throw an exception if
3653 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003654 verify(good_cert, sig, content, digest)
3655
3656 # This should fail because the certificate doesn't match the
3657 # private key that was used to sign the content.
3658 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3659
3660 # This should fail because we've "tainted" the content after
3661 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003662 self.assertRaises(
3663 Error, verify,
3664 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003665
3666 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003667 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003668 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003669 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003670 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003671
Abraham Martinc5484ba2015-03-25 15:33:05 +00003672 def test_sign_verify_with_text(self):
3673 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003674 :py:obj:`sign` generates a cryptographic signature which
3675 :py:obj:`verify` can check. Deprecation warnings raised because using
3676 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003677 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003678 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003679 b"It was a bright cold day in April, and the clocks were striking "
3680 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3681 b"effort to escape the vile wind, slipped quickly through the "
3682 b"glass doors of Victory Mansions, though not quickly enough to "
3683 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003684 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003685
3686 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3687 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3688 for digest in ['md5', 'sha1']:
3689 with catch_warnings(record=True) as w:
3690 simplefilter("always")
3691 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003692
3693 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003694 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003695 WARNING_TYPE_EXPECTED
3696 ),
3697 str(w[-1].message)
3698 )
3699 self.assertIs(w[-1].category, DeprecationWarning)
3700
Abraham Martinc5484ba2015-03-25 15:33:05 +00003701 with catch_warnings(record=True) as w:
3702 simplefilter("always")
3703 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003704
3705 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003706 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003707 WARNING_TYPE_EXPECTED
3708 ),
3709 str(w[-1].message)
3710 )
3711 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003712
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003713 def test_sign_nulls(self):
3714 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003715 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003716 """
3717 content = b("Watch out! \0 Did you see it?")
3718 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3719 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3720 sig = sign(priv_key, content, "sha1")
3721 verify(good_cert, sig, content, "sha1")
3722
Colleen Murphye09399b2016-03-01 17:40:49 -08003723 def test_sign_with_large_key(self):
3724 """
3725 :py:obj:`sign` produces a signature for a string when using a long key.
3726 """
3727 content = b(
3728 "It was a bright cold day in April, and the clocks were striking "
3729 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3730 "effort to escape the vile wind, slipped quickly through the "
3731 "glass doors of Victory Mansions, though not quickly enough to "
3732 "prevent a swirl of gritty dust from entering along with him.")
3733
3734 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3735 sign(priv_key, content, "sha1")
3736
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003737
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003738class EllipticCurveTests(TestCase):
3739 """
3740 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3741 :py:obj:`get_elliptic_curves`.
3742 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003743
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003744 def test_set(self):
3745 """
3746 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3747 """
3748 self.assertIsInstance(get_elliptic_curves(), set)
3749
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003750 def test_some_curves(self):
3751 """
3752 If :py:mod:`cryptography` has elliptic curve support then the set
3753 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3754 it.
3755
3756 There could be an OpenSSL that violates this assumption. If so, this
3757 test will fail and we'll find out.
3758 """
3759 curves = get_elliptic_curves()
3760 if lib.Cryptography_HAS_EC:
3761 self.assertTrue(curves)
3762 else:
3763 self.assertFalse(curves)
3764
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003765 def test_a_curve(self):
3766 """
3767 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3768 supported curve.
3769 """
3770 curves = get_elliptic_curves()
3771 if curves:
3772 curve = next(iter(curves))
3773 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3774 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003775 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003776
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003777 def test_not_a_curve(self):
3778 """
3779 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3780 with a name which does not identify a supported curve.
3781 """
3782 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003783 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003784
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003785 def test_repr(self):
3786 """
3787 The string representation of a curve object includes simply states the
3788 object is a curve and what its name is.
3789 """
3790 curves = get_elliptic_curves()
3791 if curves:
3792 curve = next(iter(curves))
3793 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3794
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003795 def test_to_EC_KEY(self):
3796 """
3797 The curve object can export a version of itself as an EC_KEY* via the
3798 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3799 """
3800 curves = get_elliptic_curves()
3801 if curves:
3802 curve = next(iter(curves))
3803 # It's not easy to assert anything about this object. However, see
3804 # leakcheck/crypto.py for a test that demonstrates it at least does
3805 # not leak memory.
3806 curve._to_EC_KEY()
3807
3808
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003809class EllipticCurveFactory(object):
3810 """
3811 A helper to get the names of two curves.
3812 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003813
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003814 def __init__(self):
3815 curves = iter(get_elliptic_curves())
3816 try:
3817 self.curve_name = next(curves).name
3818 self.another_curve_name = next(curves).name
3819 except StopIteration:
3820 self.curve_name = self.another_curve_name = None
3821
3822
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003823class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3824 """
3825 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3826 """
3827 curve_factory = EllipticCurveFactory()
3828
3829 if curve_factory.curve_name is None:
3830 skip = "There are no curves available there can be no curve objects."
3831
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003832 def anInstance(self):
3833 """
3834 Get the curve object for an arbitrary curve supported by the system.
3835 """
3836 return get_elliptic_curve(self.curve_factory.curve_name)
3837
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003838 def anotherInstance(self):
3839 """
3840 Get the curve object for an arbitrary curve supported by the system -
3841 but not the one returned by C{anInstance}.
3842 """
3843 return get_elliptic_curve(self.curve_factory.another_curve_name)
3844
3845
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003846class EllipticCurveHashTests(TestCase):
3847 """
3848 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3849 as an item in a :py:type:`dict` or :py:type:`set`).
3850 """
3851 curve_factory = EllipticCurveFactory()
3852
3853 if curve_factory.curve_name is None:
3854 skip = "There are no curves available there can be no curve objects."
3855
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003856 def test_contains(self):
3857 """
3858 The ``in`` operator reports that a :py:type:`set` containing a curve
3859 does contain that curve.
3860 """
3861 curve = get_elliptic_curve(self.curve_factory.curve_name)
3862 curves = set([curve])
3863 self.assertIn(curve, curves)
3864
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003865 def test_does_not_contain(self):
3866 """
3867 The ``in`` operator reports that a :py:type:`set` not containing a
3868 curve does not contain that curve.
3869 """
3870 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003871 curves = set([
3872 get_elliptic_curve(self.curve_factory.another_curve_name)
3873 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003874 self.assertNotIn(curve, curves)
3875
3876
Rick Dean5b7b6372009-04-01 11:34:06 -05003877if __name__ == '__main__':
3878 main()