blob: 81e0ae3813570ce4ab27d6f1e2f0d555da8a28ca [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"
Alex Gaynor37726112016-07-04 09:51:32 -0400962 assert name.commonName == "foo"
963 assert name.CN == "foo"
964
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500965 name.CN = "baz"
Alex Gaynor37726112016-07-04 09:51:32 -0400966 assert name.commonName == "baz"
967 assert name.CN == "baz"
968
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500969 name.commonName = "bar"
Alex Gaynor37726112016-07-04 09:51:32 -0400970 assert name.commonName == "bar"
971 assert name.CN == "bar"
972
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500973 name.CN = "quux"
Alex Gaynor37726112016-07-04 09:51:32 -0400974 assert name.commonName == "quux"
975 assert name.CN == "quux"
976
977 assert name.OU is None
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500978
Alex Gaynor7778e792016-07-03 23:38:48 -0400979 with pytest.raises(AttributeError):
980 name.foobar
981
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500982 def test_copy(self):
983 """
Alex Gaynor31287502015-09-05 16:11:27 -0400984 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
985 with all the same attributes as an existing :py:class:`X509NameType`
986 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500987 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500988 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500989
990 copy = X509Name(name)
991 self.assertEqual(copy.commonName, "foo")
992 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500993
994 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500995 copy.commonName = "baz"
996 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500997
998 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500999 name.emailAddress = "quux@example.com"
1000 self.assertEqual(copy.emailAddress, "bar@example.com")
1001
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001002 def test_repr(self):
1003 """
Alex Gaynor31287502015-09-05 16:11:27 -04001004 :py:func:`repr` passed an :py:class:`X509NameType` instance should
1005 return a string containing a description of the type and the NIDs which
1006 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001007 """
1008 name = self._x509name(commonName="foo", emailAddress="bar")
1009 self.assertEqual(
1010 repr(name),
1011 "<X509Name object '/emailAddress=bar/CN=foo'>")
1012
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001013 def test_comparison(self):
1014 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001015 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001016 """
1017 def _equality(a, b, assertTrue, assertFalse):
1018 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
1019 assertFalse(a != b)
1020 assertTrue(b == a)
1021 assertFalse(b != a)
1022
1023 def assertEqual(a, b):
1024 _equality(a, b, self.assertTrue, self.assertFalse)
1025
1026 # Instances compare equal to themselves.
1027 name = self._x509name()
1028 assertEqual(name, name)
1029
1030 # Empty instances should compare equal to each other.
1031 assertEqual(self._x509name(), self._x509name())
1032
1033 # Instances with equal NIDs should compare equal to each other.
1034 assertEqual(self._x509name(commonName="foo"),
1035 self._x509name(commonName="foo"))
1036
1037 # Instance with equal NIDs set using different aliases should compare
1038 # equal to each other.
1039 assertEqual(self._x509name(commonName="foo"),
1040 self._x509name(CN="foo"))
1041
1042 # Instances with more than one NID with the same values should compare
1043 # equal to each other.
1044 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
1045 self._x509name(commonName="foo", OU="bar"))
1046
1047 def assertNotEqual(a, b):
1048 _equality(a, b, self.assertFalse, self.assertTrue)
1049
1050 # Instances with different values for the same NID should not compare
1051 # equal to each other.
1052 assertNotEqual(self._x509name(CN="foo"),
1053 self._x509name(CN="bar"))
1054
1055 # Instances with different NIDs should not compare equal to each other.
1056 assertNotEqual(self._x509name(CN="foo"),
1057 self._x509name(OU="foo"))
1058
Alex Gaynor7778e792016-07-03 23:38:48 -04001059 assertNotEqual(self._x509name(), object())
1060
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001061 def _inequality(a, b, assertTrue, assertFalse):
1062 assertTrue(a < b)
1063 assertTrue(a <= b)
1064 assertTrue(b > a)
1065 assertTrue(b >= a)
1066 assertFalse(a > b)
1067 assertFalse(a >= b)
1068 assertFalse(b < a)
1069 assertFalse(b <= a)
1070
1071 def assertLessThan(a, b):
1072 _inequality(a, b, self.assertTrue, self.assertFalse)
1073
1074 # An X509Name with a NID with a value which sorts less than the value
1075 # of the same NID on another X509Name compares less than the other
1076 # X509Name.
1077 assertLessThan(self._x509name(CN="abc"),
1078 self._x509name(CN="def"))
1079
1080 def assertGreaterThan(a, b):
1081 _inequality(a, b, self.assertFalse, self.assertTrue)
1082
1083 # An X509Name with a NID with a value which sorts greater than the
1084 # value of the same NID on another X509Name compares greater than the
1085 # other X509Name.
1086 assertGreaterThan(self._x509name(CN="def"),
1087 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001088
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001089 def test_hash(self):
1090 """
Alex Gaynor31287502015-09-05 16:11:27 -04001091 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1092 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001093 """
1094 a = self._x509name(CN="foo")
1095 b = self._x509name(CN="foo")
1096 self.assertEqual(a.hash(), b.hash())
1097 a.CN = "bar"
1098 self.assertNotEqual(a.hash(), b.hash())
1099
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001100 def test_der(self):
1101 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001102 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001103 """
1104 a = self._x509name(CN="foo", C="US")
1105 self.assertEqual(
1106 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001107 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001108 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001109
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001110 def test_get_components(self):
1111 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001112 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1113 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001114 giving the NIDs and associated values which make up the name.
1115 """
1116 a = self._x509name()
1117 self.assertEqual(a.get_components(), [])
1118 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001119 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001120 a.organizationalUnitName = "bar"
1121 self.assertEqual(
1122 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001123 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001124
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001125 def test_load_nul_byte_attribute(self):
1126 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001127 An :py:class:`OpenSSL.crypto.X509Name` from an
1128 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001129 NUL byte in the value of one of its attributes.
1130 """
1131 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1132 subject = cert.get_subject()
1133 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001134 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001135
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001136 def test_setAttributeFailure(self):
1137 """
1138 If the value of an attribute cannot be set for some reason then
1139 :py:class:`OpenSSL.crypto.Error` is raised.
1140 """
1141 name = self._x509name()
1142 # This value is too long
1143 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1144
1145
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001146class _PKeyInteractionTestsMixin:
1147 """
1148 Tests which involve another thing and a PKey.
1149 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001150
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001151 def signable(self):
1152 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001153 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1154 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001155 """
1156 raise NotImplementedError()
1157
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001158 def test_signWithUngenerated(self):
1159 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001160 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1161 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001162 """
1163 request = self.signable()
1164 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001165 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001166
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001167 def test_signWithPublicKey(self):
1168 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001169 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1170 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001171 """
1172 request = self.signable()
1173 key = PKey()
1174 key.generate_key(TYPE_RSA, 512)
1175 request.set_pubkey(key)
1176 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001177 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001178
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001179 def test_signWithUnknownDigest(self):
1180 """
Alex Gaynor31287502015-09-05 16:11:27 -04001181 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1182 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001183 """
1184 request = self.signable()
1185 key = PKey()
1186 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001187 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001188
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001189 def test_sign(self):
1190 """
Alex Gaynor31287502015-09-05 16:11:27 -04001191 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1192 valid digest function. :py:meth:`X509Req.verify` can be used to check
1193 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001194 """
1195 request = self.signable()
1196 key = PKey()
1197 key.generate_key(TYPE_RSA, 512)
1198 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001199 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001200 # If the type has a verify method, cover that too.
1201 if getattr(request, 'verify', None) is not None:
1202 pub = request.get_pubkey()
1203 self.assertTrue(request.verify(pub))
1204 # Make another key that won't verify.
1205 key = PKey()
1206 key.generate_key(TYPE_RSA, 512)
1207 self.assertRaises(Error, request.verify, key)
1208
1209
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001210class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001211 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001212 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001213 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001214
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001215 def signable(self):
1216 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001217 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001218 """
1219 return X509Req()
1220
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001221 def test_type(self):
1222 """
Alex Gaynor31287502015-09-05 16:11:27 -04001223 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1224 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001225 """
1226 self.assertIdentical(X509Req, X509ReqType)
1227 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001228
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001229 def test_construction(self):
1230 """
Alex Gaynor31287502015-09-05 16:11:27 -04001231 :py:obj:`X509Req` takes no arguments and returns an
1232 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001233 """
1234 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001235 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001236
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001237 def test_version(self):
1238 """
Alex Gaynor31287502015-09-05 16:11:27 -04001239 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1240 certificate request. :py:obj:`X509ReqType.get_version` returns the
1241 X.509 version of the certificate request. The initial value of the
1242 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001243 """
1244 request = X509Req()
1245 self.assertEqual(request.get_version(), 0)
1246 request.set_version(1)
1247 self.assertEqual(request.get_version(), 1)
1248 request.set_version(3)
1249 self.assertEqual(request.get_version(), 3)
1250
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001251 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001252 """
Alex Gaynor31287502015-09-05 16:11:27 -04001253 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1254 with the wrong number of arguments or with a non-:py:obj:`int`
1255 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1256 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001257 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001258 request = X509Req()
1259 self.assertRaises(TypeError, request.set_version)
1260 self.assertRaises(TypeError, request.set_version, "foo")
1261 self.assertRaises(TypeError, request.set_version, 1, 2)
1262 self.assertRaises(TypeError, request.get_version, None)
1263
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001264 def test_get_subject(self):
1265 """
Alex Gaynor31287502015-09-05 16:11:27 -04001266 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1267 subject of the request and which is valid even after the request object
1268 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001269 """
1270 request = X509Req()
1271 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001272 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001273 subject.commonName = "foo"
1274 self.assertEqual(request.get_subject().commonName, "foo")
1275 del request
1276 subject.commonName = "bar"
1277 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001278
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001279 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001280 """
Alex Gaynor31287502015-09-05 16:11:27 -04001281 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1282 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001283 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001284 request = X509Req()
1285 self.assertRaises(TypeError, request.get_subject, None)
1286
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001287 def test_add_extensions(self):
1288 """
Alex Gaynor31287502015-09-05 16:11:27 -04001289 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1290 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001291 """
1292 request = X509Req()
1293 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001294 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001295 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001296 self.assertEqual(len(exts), 1)
1297 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1298 self.assertEqual(exts[0].get_critical(), 1)
1299 self.assertEqual(exts[0].get_data(), b('0\x00'))
1300
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001301 def test_get_extensions(self):
1302 """
1303 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1304 extensions added to this X509 request.
1305 """
1306 request = X509Req()
1307 exts = request.get_extensions()
1308 self.assertEqual(exts, [])
1309 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001310 X509Extension(b('basicConstraints'), True, b('CA:true')),
1311 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001312 exts = request.get_extensions()
1313 self.assertEqual(len(exts), 2)
1314 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1315 self.assertEqual(exts[0].get_critical(), 1)
1316 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1317 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1318 self.assertEqual(exts[1].get_critical(), 0)
1319 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001320
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001321 def test_add_extensions_wrong_args(self):
1322 """
Alex Gaynor31287502015-09-05 16:11:27 -04001323 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1324 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1325 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1326 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001327 """
1328 request = X509Req()
1329 self.assertRaises(TypeError, request.add_extensions)
1330 self.assertRaises(TypeError, request.add_extensions, object())
1331 self.assertRaises(ValueError, request.add_extensions, [object()])
1332 self.assertRaises(TypeError, request.add_extensions, [], None)
1333
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001334 def test_verify_wrong_args(self):
1335 """
1336 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1337 arguments or more than one argument or if passed anything other than a
1338 :py:obj:`PKey` instance as its single argument.
1339 """
1340 request = X509Req()
1341 self.assertRaises(TypeError, request.verify)
1342 self.assertRaises(TypeError, request.verify, object())
1343 self.assertRaises(TypeError, request.verify, PKey(), object())
1344
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001345 def test_verify_uninitialized_key(self):
1346 """
Alex Gaynor31287502015-09-05 16:11:27 -04001347 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1348 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001349 """
1350 request = X509Req()
1351 pkey = PKey()
1352 self.assertRaises(Error, request.verify, pkey)
1353
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001354 def test_verify_wrong_key(self):
1355 """
Alex Gaynor31287502015-09-05 16:11:27 -04001356 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1357 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1358 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001359 """
1360 request = X509Req()
1361 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001362 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001363 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1364 self.assertRaises(Error, request.verify, another_pkey)
1365
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001366 def test_verify_success(self):
1367 """
1368 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001369 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1370 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001371 """
1372 request = X509Req()
1373 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001374 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001375 self.assertEqual(True, request.verify(pkey))
1376
1377
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001378class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001379 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001380 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001381 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001382 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001383
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001384 extpem = """
1385-----BEGIN CERTIFICATE-----
1386MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1387BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1388eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1389MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1390aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1391hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1392Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1393zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1394hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1395TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
139603HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1397MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1398b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1399MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1400uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1401WpOdIpB8KksUTCzV591Nr1wd
1402-----END CERTIFICATE-----
1403 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001404
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001405 def signable(self):
1406 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001407 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001408 """
1409 return X509()
1410
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001411 def test_type(self):
1412 """
Alex Gaynor31287502015-09-05 16:11:27 -04001413 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1414 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001415 """
1416 self.assertIdentical(X509, X509Type)
1417 self.assertConsistentType(X509, 'X509')
1418
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001419 def test_construction(self):
1420 """
Alex Gaynor31287502015-09-05 16:11:27 -04001421 :py:obj:`X509` takes no arguments and returns an instance of
1422 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001423 """
1424 certificate = X509()
1425 self.assertTrue(
1426 isinstance(certificate, X509Type),
1427 "%r is of type %r, should be %r" % (certificate,
1428 type(certificate),
1429 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001430 self.assertEqual(type(X509Type).__name__, 'type')
1431 self.assertEqual(type(certificate).__name__, 'X509')
1432 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001433 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001434
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001435 def test_get_version_wrong_args(self):
1436 """
Alex Gaynor31287502015-09-05 16:11:27 -04001437 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1438 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001439 """
1440 cert = X509()
1441 self.assertRaises(TypeError, cert.get_version, None)
1442
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001443 def test_set_version_wrong_args(self):
1444 """
Alex Gaynor31287502015-09-05 16:11:27 -04001445 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1446 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001447 """
1448 cert = X509()
1449 self.assertRaises(TypeError, cert.set_version)
1450 self.assertRaises(TypeError, cert.set_version, None)
1451 self.assertRaises(TypeError, cert.set_version, 1, None)
1452
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001453 def test_version(self):
1454 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001455 :py:obj:`X509.set_version` sets the certificate version number.
1456 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001457 """
1458 cert = X509()
1459 cert.set_version(1234)
1460 self.assertEquals(cert.get_version(), 1234)
1461
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001462 def test_get_serial_number_wrong_args(self):
1463 """
Alex Gaynor31287502015-09-05 16:11:27 -04001464 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1465 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001466 """
1467 cert = X509()
1468 self.assertRaises(TypeError, cert.get_serial_number, None)
1469
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001470 def test_serial_number(self):
1471 """
Alex Gaynor31287502015-09-05 16:11:27 -04001472 The serial number of an :py:obj:`X509Type` can be retrieved and
1473 modified with :py:obj:`X509Type.get_serial_number` and
1474 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001475 """
1476 certificate = X509()
1477 self.assertRaises(TypeError, certificate.set_serial_number)
1478 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1479 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1480 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1481 self.assertEqual(certificate.get_serial_number(), 0)
1482 certificate.set_serial_number(1)
1483 self.assertEqual(certificate.get_serial_number(), 1)
1484 certificate.set_serial_number(2 ** 32 + 1)
1485 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1486 certificate.set_serial_number(2 ** 64 + 1)
1487 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001488 certificate.set_serial_number(2 ** 128 + 1)
1489 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1490
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001491 def _setBoundTest(self, which):
1492 """
Alex Gaynor31287502015-09-05 16:11:27 -04001493 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1494 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1495 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001496 """
1497 certificate = X509()
1498 set = getattr(certificate, 'set_not' + which)
1499 get = getattr(certificate, 'get_not' + which)
1500
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001501 # Starts with no value.
1502 self.assertEqual(get(), None)
1503
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001504 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001505 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001506 set(when)
1507 self.assertEqual(get(), when)
1508
1509 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001510 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001511 set(when)
1512 self.assertEqual(get(), when)
1513
1514 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001515 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001516 set(when)
1517 self.assertEqual(get(), when)
1518
1519 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001520 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001521
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001522 # The wrong number of arguments results in a TypeError.
1523 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001524 with pytest.raises(TypeError):
1525 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001526 self.assertRaises(TypeError, get, b("foo bar"))
1527
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001528 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001529
1530 def test_set_notBefore(self):
1531 """
Alex Gaynor31287502015-09-05 16:11:27 -04001532 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1533 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1534 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001535 """
1536 self._setBoundTest("Before")
1537
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001538 def test_set_notAfter(self):
1539 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001540 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001541 GENERALIZEDTIME and sets the end of the certificate's validity period
1542 to it.
1543 """
1544 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001545
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001546 def test_get_notBefore(self):
1547 """
Alex Gaynor31287502015-09-05 16:11:27 -04001548 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1549 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001550 internally.
1551 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001552 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001553 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001554
Rick Dean38a05c82009-07-18 01:41:30 -05001555 def test_get_notAfter(self):
1556 """
Alex Gaynor31287502015-09-05 16:11:27 -04001557 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1558 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001559 internally.
1560 """
1561 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001562 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001563
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001564 def test_gmtime_adj_notBefore_wrong_args(self):
1565 """
Alex Gaynor31287502015-09-05 16:11:27 -04001566 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1567 called with the wrong number of arguments or a non-:py:obj:`int`
1568 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001569 """
1570 cert = X509()
1571 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1572 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1573 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1574
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001575 def test_gmtime_adj_notBefore(self):
1576 """
Alex Gaynor31287502015-09-05 16:11:27 -04001577 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1578 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001579 """
1580 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001581 not_before_min = (
1582 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1583 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001584 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001585 not_before = datetime.strptime(
1586 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1587 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001588 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1589 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001590
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001591 def test_gmtime_adj_notAfter_wrong_args(self):
1592 """
Alex Gaynor31287502015-09-05 16:11:27 -04001593 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1594 called with the wrong number of arguments or a non-:py:obj:`int`
1595 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001596 """
1597 cert = X509()
1598 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1599 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1600 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1601
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001602 def test_gmtime_adj_notAfter(self):
1603 """
Alex Gaynor31287502015-09-05 16:11:27 -04001604 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1605 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001606 """
1607 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001608 not_after_min = (
1609 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1610 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001611 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001612 not_after = datetime.strptime(
1613 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1614 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001615 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1616 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001617
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001618 def test_has_expired_wrong_args(self):
1619 """
Alex Gaynor31287502015-09-05 16:11:27 -04001620 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1621 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001622 """
1623 cert = X509()
1624 self.assertRaises(TypeError, cert.has_expired, None)
1625
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001626 def test_has_expired(self):
1627 """
Alex Gaynor31287502015-09-05 16:11:27 -04001628 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1629 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001630 """
1631 cert = X509()
1632 cert.gmtime_adj_notAfter(-1)
1633 self.assertTrue(cert.has_expired())
1634
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001635 def test_has_not_expired(self):
1636 """
Alex Gaynor31287502015-09-05 16:11:27 -04001637 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1638 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001639 """
1640 cert = X509()
1641 cert.gmtime_adj_notAfter(2)
1642 self.assertFalse(cert.has_expired())
1643
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001644 def test_root_has_not_expired(self):
1645 """
Alex Gaynor31287502015-09-05 16:11:27 -04001646 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1647 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001648 """
1649 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1650 self.assertFalse(cert.has_expired())
1651
Rick Dean38a05c82009-07-18 01:41:30 -05001652 def test_digest(self):
1653 """
Alex Gaynor31287502015-09-05 16:11:27 -04001654 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1655 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001656 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001657 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001658 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001659 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1660 # actually matters to the assertion (ie, another arbitrary, good
1661 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001662 # Digest verified with the command:
1663 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001664 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001665 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001666
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001667 def _extcert(self, pkey, extensions):
1668 cert = X509()
1669 cert.set_pubkey(pkey)
1670 cert.get_subject().commonName = "Unit Tests"
1671 cert.get_issuer().commonName = "Unit Tests"
1672 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1673 cert.set_notBefore(when)
1674 cert.set_notAfter(when)
1675
1676 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001677 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001678 return load_certificate(
1679 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1680
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001681 def test_extension_count(self):
1682 """
Alex Gaynor31287502015-09-05 16:11:27 -04001683 :py:obj:`X509.get_extension_count` returns the number of extensions
1684 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001685 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001686 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001687 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1688 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001689 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001690 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001691
1692 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001693 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001694 self.assertEqual(c.get_extension_count(), 0)
1695
1696 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001697 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001698 self.assertEqual(c.get_extension_count(), 1)
1699
1700 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001701 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001702 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001703
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001704 def test_get_extension(self):
1705 """
Alex Gaynor31287502015-09-05 16:11:27 -04001706 :py:obj:`X509.get_extension` takes an integer and returns an
1707 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001708 """
1709 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001710 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1711 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001712 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001713 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001714
1715 cert = self._extcert(pkey, [ca, key, subjectAltName])
1716
1717 ext = cert.get_extension(0)
1718 self.assertTrue(isinstance(ext, X509Extension))
1719 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001720 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001721
1722 ext = cert.get_extension(1)
1723 self.assertTrue(isinstance(ext, X509Extension))
1724 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001725 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001726
1727 ext = cert.get_extension(2)
1728 self.assertTrue(isinstance(ext, X509Extension))
1729 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001730 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001731
1732 self.assertRaises(IndexError, cert.get_extension, -1)
1733 self.assertRaises(IndexError, cert.get_extension, 4)
1734 self.assertRaises(TypeError, cert.get_extension, "hello")
1735
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001736 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001737 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001738 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001739 bytes and this value is reflected in the string representation of the
1740 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001741 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001742 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001743
1744 ext = cert.get_extension(3)
1745 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001746 self.assertEqual(
1747 b("DNS:altnull.python.org\x00example.com, "
1748 "email:null@python.org\x00user@example.org, "
1749 "URI:http://null.python.org\x00http://example.org, "
1750 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1751 b(str(ext)))
1752
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001753 def test_invalid_digest_algorithm(self):
1754 """
Alex Gaynor31287502015-09-05 16:11:27 -04001755 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1756 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001757 """
1758 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001759 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001760
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001761 def test_get_subject_wrong_args(self):
1762 """
Alex Gaynor31287502015-09-05 16:11:27 -04001763 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1764 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001765 """
1766 cert = X509()
1767 self.assertRaises(TypeError, cert.get_subject, None)
1768
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001769 def test_get_subject(self):
1770 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001771 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001772 """
1773 cert = load_certificate(FILETYPE_PEM, self.pemData)
1774 subj = cert.get_subject()
1775 self.assertTrue(isinstance(subj, X509Name))
1776 self.assertEquals(
1777 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001778 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1779 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001780
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001781 def test_set_subject_wrong_args(self):
1782 """
Alex Gaynor31287502015-09-05 16:11:27 -04001783 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1784 the wrong number of arguments or an argument not of type
1785 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001786 """
1787 cert = X509()
1788 self.assertRaises(TypeError, cert.set_subject)
1789 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001790 with pytest.raises(TypeError):
1791 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001792
1793 def test_set_subject(self):
1794 """
Alex Gaynor31287502015-09-05 16:11:27 -04001795 :py:obj:`X509.set_subject` changes the subject of the certificate to
1796 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001797 """
1798 cert = X509()
1799 name = cert.get_subject()
1800 name.C = 'AU'
1801 name.O = 'Unit Tests'
1802 cert.set_subject(name)
1803 self.assertEquals(
1804 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001805 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001806
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001807 def test_get_issuer_wrong_args(self):
1808 """
Alex Gaynor31287502015-09-05 16:11:27 -04001809 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1810 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001811 """
1812 cert = X509()
1813 self.assertRaises(TypeError, cert.get_issuer, None)
1814
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001815 def test_get_issuer(self):
1816 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001817 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001818 """
1819 cert = load_certificate(FILETYPE_PEM, self.pemData)
1820 subj = cert.get_issuer()
1821 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001822 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001823 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001824 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001825 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1826 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001827
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001828 def test_set_issuer_wrong_args(self):
1829 """
Alex Gaynor31287502015-09-05 16:11:27 -04001830 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1831 the wrong number of arguments or an argument not of type
1832 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001833 """
1834 cert = X509()
1835 self.assertRaises(TypeError, cert.set_issuer)
1836 self.assertRaises(TypeError, cert.set_issuer, None)
1837 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1838
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001839 def test_set_issuer(self):
1840 """
Alex Gaynor31287502015-09-05 16:11:27 -04001841 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1842 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001843 """
1844 cert = X509()
1845 name = cert.get_issuer()
1846 name.C = 'AU'
1847 name.O = 'Unit Tests'
1848 cert.set_issuer(name)
1849 self.assertEquals(
1850 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001851 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001852
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001853 def test_get_pubkey_uninitialized(self):
1854 """
Alex Gaynor31287502015-09-05 16:11:27 -04001855 When called on a certificate with no public key,
1856 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001857 """
1858 cert = X509()
1859 self.assertRaises(Error, cert.get_pubkey)
1860
Alex Gaynor7778e792016-07-03 23:38:48 -04001861 def test_set_pubkey_wrong_type(self):
1862 """
1863 :obj:`X509.set_pubkey` raises :obj:`TypeError` when given an object of
1864 the wrong type.
1865 """
1866 cert = X509()
1867 with pytest.raises(TypeError):
1868 cert.set_pubkey(object())
1869
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001870 def test_subject_name_hash_wrong_args(self):
1871 """
Alex Gaynor31287502015-09-05 16:11:27 -04001872 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1873 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001874 """
1875 cert = X509()
1876 self.assertRaises(TypeError, cert.subject_name_hash, None)
1877
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001878 def test_subject_name_hash(self):
1879 """
Alex Gaynor31287502015-09-05 16:11:27 -04001880 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1881 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001882 """
1883 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001884 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001885 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001886 [3350047874, # OpenSSL 0.9.8, MD5
1887 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001888 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001889
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001890 def test_get_signature_algorithm(self):
1891 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001892 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001893 the algorithm used to sign the certificate.
1894 """
1895 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001896 self.assertEqual(
1897 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001898
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001899 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001900 """
Alex Gaynor31287502015-09-05 16:11:27 -04001901 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1902 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001903 """
1904 # This certificate has been modified to indicate a bogus OID in the
1905 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001906 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001907-----BEGIN CERTIFICATE-----
1908MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1909EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1910cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1911MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1912EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1913CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1914AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1915+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1916hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1917BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1918FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1919dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1920aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1921MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1922jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1923PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1924tgI5
1925-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001926""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001927 cert = load_certificate(FILETYPE_PEM, certPEM)
1928 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001929
Alex Gaynor37726112016-07-04 09:51:32 -04001930 def test_sign_bad_pubkey_type(self):
1931 """
1932 :obj:`X509.sign` raises :obj:`TypeError` when called with the wrong
1933 type.
1934 """
1935 cert = X509()
1936 with pytest.raises(TypeError):
1937 cert.sign(object(), b"sha256")
1938
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001939
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001940class X509StoreTests(TestCase):
1941 """
1942 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1943 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001944
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001945 def test_type(self):
1946 """
1947 :py:obj:`X509StoreType` is a type object.
1948 """
1949 self.assertIdentical(X509Store, X509StoreType)
1950 self.assertConsistentType(X509Store, 'X509Store')
1951
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001952 def test_add_cert_wrong_args(self):
1953 store = X509Store()
1954 self.assertRaises(TypeError, store.add_cert)
1955 self.assertRaises(TypeError, store.add_cert, object())
1956 self.assertRaises(TypeError, store.add_cert, X509(), object())
1957
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001958 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001959 """
1960 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1961 certificate store.
1962 """
1963 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001964 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001965 store.add_cert(cert)
1966
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001967 def test_add_cert_rejects_duplicate(self):
1968 """
Alex Gaynor31287502015-09-05 16:11:27 -04001969 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1970 an attempt is made to add the same certificate to the store more than
1971 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001972 """
1973 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1974 store = X509Store()
1975 store.add_cert(cert)
1976 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001977
1978
Rick Dean623ee362009-07-17 12:22:16 -05001979class PKCS12Tests(TestCase):
1980 """
Alex Gaynor31287502015-09-05 16:11:27 -04001981 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1982 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001983 """
1984 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1985
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001986 def test_type(self):
1987 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001988 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001989 """
1990 self.assertIdentical(PKCS12, PKCS12Type)
1991 self.assertConsistentType(PKCS12, 'PKCS12')
1992
Rick Deanf94096c2009-07-18 14:23:06 -05001993 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001994 """
Alex Gaynor31287502015-09-05 16:11:27 -04001995 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1996 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001997 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001998 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001999 self.assertEqual(None, p12.get_certificate())
2000 self.assertEqual(None, p12.get_privatekey())
2001 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05002002 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05002003
2004 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002005 """
Alex Gaynor31287502015-09-05 16:11:27 -04002006 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
2007 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
2008 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
2009 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05002010 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002011 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05002012 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002013 self.assertRaises(TypeError, p12.set_certificate, PKey())
2014 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05002015 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002016 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
2017 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05002018 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
2019 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
2020 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04002021 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05002022 self.assertRaises(TypeError, p12.set_friendlyname, 6)
2023 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05002024
2025 def test_key_only(self):
2026 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002027 A :py:obj:`PKCS12` with only a private key can be exported using
2028 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002029 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002030 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002031 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002032 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002033 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05002034 self.assertEqual(None, p12.get_certificate())
2035 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002036 try:
2037 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2038 except Error:
2039 # Some versions of OpenSSL will throw an exception
2040 # for this nearly useless PKCS12 we tried to generate:
2041 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2042 return
Rick Dean623ee362009-07-17 12:22:16 -05002043 p12 = load_pkcs12(dumped_p12, passwd)
2044 self.assertEqual(None, p12.get_ca_certificates())
2045 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002046
2047 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2048 # future this will be improved.
2049 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05002050
2051 def test_cert_only(self):
2052 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002053 A :py:obj:`PKCS12` with only a certificate can be exported using
2054 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002055 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002056 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002057 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002058 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002059 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05002060 self.assertEqual(cert, p12.get_certificate())
2061 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002062 try:
2063 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2064 except Error:
2065 # Some versions of OpenSSL will throw an exception
2066 # for this nearly useless PKCS12 we tried to generate:
2067 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2068 return
Rick Dean623ee362009-07-17 12:22:16 -05002069 p12 = load_pkcs12(dumped_p12, passwd)
2070 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002071
2072 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
2073 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2074
2075 # Oh ho. It puts the certificate into the ca certificates list, in
2076 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2077 # that to check to see if it reconstructed the certificate we expected
2078 # it to. At some point, hopefully this will change so that
2079 # p12.get_certificate() is actually what returns the loaded
2080 # certificate.
2081 self.assertEqual(
2082 cleartextCertificatePEM,
2083 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002084
Alex Gaynor31287502015-09-05 16:11:27 -04002085 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2086 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002087 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002088 Generate a PKCS12 object with components from PEM. Verify that the set
2089 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002090 """
Rick Deanf94096c2009-07-18 14:23:06 -05002091 p12 = PKCS12()
2092 if cert_pem:
2093 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2094 self.assertEqual(ret, None)
2095 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002096 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002097 self.assertEqual(ret, None)
2098 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002099 ret = p12.set_ca_certificates(
2100 (load_certificate(FILETYPE_PEM, ca_pem),)
2101 )
Rick Deanf94096c2009-07-18 14:23:06 -05002102 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002103 if friendly_name:
2104 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002105 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002106 return p12
2107
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002108 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002109 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002110 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002111 Use openssl program to confirm three components are recoverable from a
2112 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002113 """
2114 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002115 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002116 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2117 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002118 self.assertEqual(recovered_key[-len(key):], key)
2119 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002120 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002121 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2122 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002123 self.assertEqual(recovered_cert[-len(cert):], cert)
2124 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002125 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002126 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2127 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002128 self.assertEqual(recovered_cert[-len(ca):], ca)
2129
Stephen Holsapple38482622014-04-05 20:29:34 -07002130 def verify_pkcs12_container(self, p12):
2131 """
2132 Verify that the PKCS#12 container contains the correct client
2133 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002134
2135 :param p12: The PKCS12 instance to verify.
2136 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002137 """
2138 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2139 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002140 self.assertEqual(
2141 (client_cert_pem, client_key_pem, None),
2142 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002143
Rick Deanf94096c2009-07-18 14:23:06 -05002144 def test_load_pkcs12(self):
2145 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002146 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002147 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002148 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002149 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002150 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002151 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002152 pem,
2153 b"pkcs12",
2154 b"-export",
2155 b"-clcerts",
2156 b"-passout",
2157 b"pass:" + passwd
2158 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002159 p12 = load_pkcs12(p12_str, passphrase=passwd)
2160 self.verify_pkcs12_container(p12)
2161
Abraham Martinc5484ba2015-03-25 15:33:05 +00002162 def test_load_pkcs12_text_passphrase(self):
2163 """
2164 A PKCS12 string generated using the openssl command line can be loaded
2165 with :py:obj:`load_pkcs12` and its components extracted and examined.
2166 Using text as passphrase instead of bytes. DeprecationWarning expected.
2167 """
2168 pem = client_key_pem + client_cert_pem
2169 passwd = b"whatever"
2170 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2171 b"-passout", b"pass:" + passwd)
2172 with catch_warnings(record=True) as w:
2173 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002174 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002175
2176 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002177 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002178 WARNING_TYPE_EXPECTED
2179 ),
2180 str(w[-1].message)
2181 )
2182 self.assertIs(w[-1].category, DeprecationWarning)
2183
Abraham Martinc5484ba2015-03-25 15:33:05 +00002184 self.verify_pkcs12_container(p12)
2185
Stephen Holsapple38482622014-04-05 20:29:34 -07002186 def test_load_pkcs12_no_passphrase(self):
2187 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002188 A PKCS12 string generated using openssl command line can be loaded with
2189 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2190 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002191 """
2192 pem = client_key_pem + client_cert_pem
2193 p12_str = _runopenssl(
2194 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2195 p12 = load_pkcs12(p12_str)
2196 self.verify_pkcs12_container(p12)
2197
Stephen Holsapple38482622014-04-05 20:29:34 -07002198 def _dump_and_load(self, dump_passphrase, load_passphrase):
2199 """
2200 A helper method to dump and load a PKCS12 object.
2201 """
2202 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2203 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2204 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2205
Stephen Holsapple38482622014-04-05 20:29:34 -07002206 def test_load_pkcs12_null_passphrase_load_empty(self):
2207 """
2208 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002209 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002210 extracted and examined.
2211 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002212 self.verify_pkcs12_container(
2213 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002214
Stephen Holsapple38482622014-04-05 20:29:34 -07002215 def test_load_pkcs12_null_passphrase_load_null(self):
2216 """
2217 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002218 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002219 extracted and examined.
2220 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002221 self.verify_pkcs12_container(
2222 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002223
Stephen Holsapple38482622014-04-05 20:29:34 -07002224 def test_load_pkcs12_empty_passphrase_load_empty(self):
2225 """
2226 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002227 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002228 extracted and examined.
2229 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002230 self.verify_pkcs12_container(
2231 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002232
Stephen Holsapple38482622014-04-05 20:29:34 -07002233 def test_load_pkcs12_empty_passphrase_load_null(self):
2234 """
2235 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002236 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002237 extracted and examined.
2238 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002239 self.verify_pkcs12_container(
2240 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002241
Rick Deanee568302009-07-24 09:56:29 -05002242 def test_load_pkcs12_garbage(self):
2243 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002244 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2245 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002246 """
2247 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002248 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002249 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2250 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002251
Rick Deanf94096c2009-07-18 14:23:06 -05002252 def test_replace(self):
2253 """
Alex Gaynor31287502015-09-05 16:11:27 -04002254 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2255 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002256 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002257 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002258 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2259 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2260 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002261 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002262 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002263 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002264 self.assertEqual(1, len(p12.get_ca_certificates()))
2265 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002266 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002267 self.assertEqual(2, len(p12.get_ca_certificates()))
2268 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2269 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2270
Rick Deanf94096c2009-07-18 14:23:06 -05002271 def test_friendly_name(self):
2272 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002273 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002274 :py:obj:`PKCS12.get_friendlyname` and
2275 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2276 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002277 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002278 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002279 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002280 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002281 p12.set_friendlyname(friendly_name)
2282 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002283 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002284 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002285 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002286 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002287 # We would use the openssl program to confirm the friendly
2288 # name, but it is not possible. The pkcs12 command
2289 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002290 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002291 self.check_recovery(
2292 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2293 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002294
Rick Deanf94096c2009-07-18 14:23:06 -05002295 def test_various_empty_passphrases(self):
2296 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002297 Test that missing, None, and '' passphrases are identical for PKCS12
2298 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002299 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002300 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002301 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002302 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2303 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2304 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2305 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2306 self.check_recovery(
2307 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2308 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002309
Rick Deanf94096c2009-07-18 14:23:06 -05002310 def test_removing_ca_cert(self):
2311 """
Alex Gaynor31287502015-09-05 16:11:27 -04002312 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2313 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002314 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002315 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2316 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002317 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002318
Rick Deanf94096c2009-07-18 14:23:06 -05002319 def test_export_without_mac(self):
2320 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002321 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002322 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002323 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002324 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002325 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002326 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002327 self.check_recovery(
2328 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002329 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002330
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002331 def test_load_without_mac(self):
2332 """
2333 Loading a PKCS12 without a MAC does something other than crash.
2334 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002335 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002336 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2337 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002338 try:
2339 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2340 # The person who generated this PCKS12 should be flogged,
2341 # or better yet we should have a means to determine
2342 # whether a PCKS12 had a MAC that was verified.
2343 # Anyway, libopenssl chooses to allow it, so the
2344 # pyopenssl binding does as well.
2345 self.assertTrue(isinstance(recovered_p12, PKCS12))
2346 except Error:
2347 # Failing here with an exception is preferred as some openssl
2348 # versions do.
2349 pass
Rick Dean623ee362009-07-17 12:22:16 -05002350
Rick Dean25bcc1f2009-07-20 11:53:13 -05002351 def test_zero_len_list_for_ca(self):
2352 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002353 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002354 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002355 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002356 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002357 p12.set_ca_certificates([])
2358 self.assertEqual((), p12.get_ca_certificates())
2359 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2360 self.check_recovery(
2361 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2362 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002363
Rick Deanf94096c2009-07-18 14:23:06 -05002364 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002365 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002366 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002367 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002368 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002369 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002370 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002371 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002372
Abraham Martinc5484ba2015-03-25 15:33:05 +00002373 def test_export_without_bytes(self):
2374 """
2375 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2376 """
2377 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2378
2379 with catch_warnings(record=True) as w:
2380 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002381 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002382 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002383 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002384 WARNING_TYPE_EXPECTED
2385 ),
2386 str(w[-1].message)
2387 )
2388 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002389 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002390 dumped_p12,
2391 key=server_key_pem,
2392 cert=server_cert_pem,
2393 passwd=b"randomtext"
2394 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002395
Rick Deanf94096c2009-07-18 14:23:06 -05002396 def test_key_cert_mismatch(self):
2397 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002398 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002399 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002400 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002401 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2402 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002403
2404
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002405# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002406_cmdLineQuoteRe = re.compile(br'(\\*)"')
2407_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002408
2409
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002410def cmdLineQuote(s):
2411 """
2412 Internal method for quoting a single command-line argument.
2413
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002414 See http://www.perlmonks.org/?node_id=764004
2415
Jonathan Ballet648875f2011-07-16 14:14:58 +09002416 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002417 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002418 cmd.exe-style quoting
2419
Jonathan Ballet648875f2011-07-16 14:14:58 +09002420 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002421 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002422 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002423 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2424 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002425
2426
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002427def quoteArguments(arguments):
2428 """
2429 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002430 a similar API. This allows the list passed to
2431 :py:obj:`reactor.spawnProcess` to match the child process's
2432 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002433
Jonathan Ballet648875f2011-07-16 14:14:58 +09002434 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002435 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002436
Jonathan Ballet648875f2011-07-16 14:14:58 +09002437 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002438 :return: A space-delimited string containing quoted versions of
2439 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002440 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002441 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002442
2443
Rick Dean4c9ad612009-07-17 15:05:22 -05002444def _runopenssl(pem, *args):
2445 """
2446 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002447 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002448 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002449 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002450 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002451 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2452 for arg in args
2453 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002454 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002455 command = b"openssl " + quoteArguments(args)
2456 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002457 proc.stdin.write(pem)
2458 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002459 output = proc.stdout.read()
2460 proc.stdout.close()
2461 proc.wait()
2462 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002463
2464
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002465class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002466 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002467 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002468 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002469 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002470 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002471 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002472 """
2473 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002474
2475 assert True is key._only_public
2476 assert 2048 == key.bits()
2477 assert TYPE_RSA == key.type()
2478
2479 def test_invalid_type(self):
2480 """
2481 load_publickey doesn't support FILETYPE_TEXT.
2482 """
2483 with pytest.raises(ValueError):
2484 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2485
2486 def test_invalid_key_format(self):
2487 """
2488 load_publickey explodes on incorrect keys.
2489 """
2490 with pytest.raises(Error):
2491 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2492
2493 def test_tolerates_unicode_strings(self):
2494 """
2495 load_publickey works with text strings, not just bytes.
2496 """
2497 serialized = cleartextPublicKeyPEM.decode('ascii')
2498 key = load_publickey(FILETYPE_PEM, serialized)
2499 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2500
2501 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002502
2503
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002504class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002505 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002506 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002507
2508 Add new tests to `TestFunctions` above.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002509 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002510
2511 def test_load_privatekey_invalid_format(self):
2512 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002513 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2514 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002515 """
2516 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2517
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002518 def test_load_privatekey_invalid_passphrase_type(self):
2519 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002520 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2521 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002522 """
2523 self.assertRaises(
2524 TypeError,
2525 load_privatekey,
2526 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2527
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002528 def test_load_privatekey_wrong_args(self):
2529 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002530 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2531 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002532 """
2533 self.assertRaises(TypeError, load_privatekey)
2534
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002535 def test_load_privatekey_wrongPassphrase(self):
2536 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002537 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2538 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002539 """
2540 self.assertRaises(
2541 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002542 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002543
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002544 def test_load_privatekey_passphraseWrongType(self):
2545 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002546 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2547 a passphrase with a private key encoded in a format, that doesn't
2548 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002549 """
2550 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2551 blob = dump_privatekey(FILETYPE_ASN1, key)
2552 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002553 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002554
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002555 def test_load_privatekey_passphrase(self):
2556 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002557 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2558 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002559 """
2560 key = load_privatekey(
2561 FILETYPE_PEM, encryptedPrivateKeyPEM,
2562 encryptedPrivateKeyPEMPassphrase)
2563 self.assertTrue(isinstance(key, PKeyType))
2564
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002565 def test_load_privatekey_passphrase_exception(self):
2566 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002567 If the passphrase callback raises an exception, that exception is
2568 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002569 """
2570 def cb(ignored):
2571 raise ArithmeticError
2572
Alex Gaynor791212d2015-09-05 15:46:08 -04002573 with pytest.raises(ArithmeticError):
2574 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002575
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002576 def test_load_privatekey_wrongPassphraseCallback(self):
2577 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002578 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2579 is passed an encrypted PEM and a passphrase callback which returns an
2580 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002581 """
2582 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002583
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002584 def cb(*a):
2585 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002586 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002587 self.assertRaises(
2588 Error,
2589 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2590 self.assertTrue(called)
2591
2592 def test_load_privatekey_passphraseCallback(self):
2593 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002594 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2595 encrypted PEM string if given a passphrase callback which returns the
2596 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002597 """
2598 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002599
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002600 def cb(writing):
2601 called.append(writing)
2602 return encryptedPrivateKeyPEMPassphrase
2603 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2604 self.assertTrue(isinstance(key, PKeyType))
2605 self.assertEqual(called, [False])
2606
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002607 def test_load_privatekey_passphrase_wrong_return_type(self):
2608 """
2609 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2610 callback returns something other than a byte string.
2611 """
2612 self.assertRaises(
2613 ValueError,
2614 load_privatekey,
2615 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2616
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002617 def test_dump_privatekey_wrong_args(self):
2618 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002619 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2620 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002621 """
2622 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002623 # If cipher name is given, password is required.
2624 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002625 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002626
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002627 def test_dump_privatekey_unknown_cipher(self):
2628 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002629 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2630 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002631 """
2632 key = PKey()
2633 key.generate_key(TYPE_RSA, 512)
2634 self.assertRaises(
2635 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002636 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002637
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002638 def test_dump_privatekey_invalid_passphrase_type(self):
2639 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002640 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2641 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002642 """
2643 key = PKey()
2644 key.generate_key(TYPE_RSA, 512)
2645 self.assertRaises(
2646 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002647 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002648
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002649 def test_dump_privatekey_invalid_filetype(self):
2650 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002651 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2652 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002653 """
2654 key = PKey()
2655 key.generate_key(TYPE_RSA, 512)
2656 self.assertRaises(ValueError, dump_privatekey, 100, key)
2657
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002658 def test_load_privatekey_passphraseCallbackLength(self):
2659 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002660 :py:obj:`crypto.load_privatekey` should raise an error when the
2661 passphrase provided by the callback is too long, not silently truncate
2662 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002663 """
2664 def cb(ignored):
2665 return "a" * 1025
2666
Alex Gaynor791212d2015-09-05 15:46:08 -04002667 with pytest.raises(ValueError):
2668 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002669
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002670 def test_dump_privatekey_passphrase(self):
2671 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002672 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2673 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002674 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002675 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002676 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002677 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2678 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002679 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2680 self.assertTrue(isinstance(loadedKey, PKeyType))
2681 self.assertEqual(loadedKey.type(), key.type())
2682 self.assertEqual(loadedKey.bits(), key.bits())
2683
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002684 def test_dump_privatekey_passphraseWrongType(self):
2685 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002686 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2687 a passphrase with a private key encoded in a format, that doesn't
2688 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002689 """
2690 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002691 with pytest.raises(ValueError):
2692 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002693
Rick Dean5b7b6372009-04-01 11:34:06 -05002694 def test_dump_certificate(self):
2695 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002696 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002697 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002698 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002699 cert = load_certificate(FILETYPE_PEM, pemData)
2700 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2701 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2702 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002703 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002704 self.assertEqual(dumped_der, good_der)
2705 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2706 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2707 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2708 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002709 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002710 self.assertEqual(dumped_text, good_text)
2711
Alex Gaynor37726112016-07-04 09:51:32 -04002712 def test_dump_certificate_bad_type(self):
2713 """
2714 :obj:`dump_certificate` raises a :obj:`ValueError` if it's called with
2715 a bad type.
2716 """
2717 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2718 with pytest.raises(ValueError):
2719 dump_certificate(object(), cert)
2720
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002721 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002722 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002723 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002724 """
2725 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002726 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002727 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2728 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002729
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002730 def test_dump_privatekey_asn1(self):
2731 """
2732 :py:obj:`dump_privatekey` writes a DER
2733 """
2734 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2735 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2736
Rick Dean5b7b6372009-04-01 11:34:06 -05002737 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002738 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002739 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002740 self.assertEqual(dumped_der, good_der)
2741 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2742 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2743 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002744
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002745 def test_dump_privatekey_text(self):
2746 """
2747 :py:obj:`dump_privatekey` writes a text
2748 """
2749 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2750 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2751
Rick Dean5b7b6372009-04-01 11:34:06 -05002752 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002753 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002754 self.assertEqual(dumped_text, good_text)
2755
Cory Benfield6492f7c2015-10-27 16:57:58 +09002756 def test_dump_publickey_pem(self):
2757 """
Cory Benfield11c10192015-10-27 17:23:03 +09002758 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002759 """
2760 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2761 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002762 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002763
2764 def test_dump_publickey_asn1(self):
2765 """
Cory Benfield11c10192015-10-27 17:23:03 +09002766 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002767 """
2768 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2769 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2770 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2771 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002772 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002773
Cory Benfielde02c7d82015-10-27 17:34:49 +09002774 def test_dump_publickey_invalid_type(self):
2775 """
2776 dump_publickey doesn't support FILETYPE_TEXT.
2777 """
2778 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2779
2780 with pytest.raises(ValueError):
2781 dump_publickey(FILETYPE_TEXT, key)
2782
Rick Dean5b7b6372009-04-01 11:34:06 -05002783 def test_dump_certificate_request(self):
2784 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002785 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002786 """
Alex Gaynor31287502015-09-05 16:11:27 -04002787 req = load_certificate_request(
2788 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002789 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2790 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2791 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002792 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002793 self.assertEqual(dumped_der, good_der)
2794 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2795 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2796 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2797 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002798 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002799 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002800 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002801
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002802 def test_dump_privatekey_passphraseCallback(self):
2803 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002804 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2805 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002806 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002807 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002808 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002809
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002810 def cb(writing):
2811 called.append(writing)
2812 return passphrase
2813 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002814 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2815 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002816 self.assertEqual(called, [True])
2817 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2818 self.assertTrue(isinstance(loadedKey, PKeyType))
2819 self.assertEqual(loadedKey.type(), key.type())
2820 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002821
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002822 def test_dump_privatekey_passphrase_exception(self):
2823 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002824 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002825 by the passphrase callback.
2826 """
2827 def cb(ignored):
2828 raise ArithmeticError
2829
2830 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002831 with pytest.raises(ArithmeticError):
2832 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002833
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002834 def test_dump_privatekey_passphraseCallbackLength(self):
2835 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002836 :py:obj:`crypto.dump_privatekey` should raise an error when the
2837 passphrase provided by the callback is too long, not silently truncate
2838 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002839 """
2840 def cb(ignored):
2841 return "a" * 1025
2842
2843 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002844 with pytest.raises(ValueError):
2845 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002846
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002847 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002848 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002849 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2850 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002851 """
2852 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2853 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2854
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002855 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002856 """
2857 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2858 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2859 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002860 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2861 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2862
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002863 def test_load_pkcs7_data_invalid(self):
2864 """
2865 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2866 :py:obj:`Error` is raised.
2867 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002868 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002869
Alex Gaynor09a386e2016-07-03 09:32:44 -04002870 def test_load_pkcs7_type_invalid(self):
2871 """
2872 If the type passed to :obj:`load_pkcs7_data`, :obj:`ValueError` is
2873 raised.
2874 """
2875 with pytest.raises(ValueError):
2876 load_pkcs7_data(object(), b"foo")
2877
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002878
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002879class LoadCertificateTests(TestCase):
2880 """
2881 Tests for :py:obj:`load_certificate_request`.
2882 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002883
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002884 def test_badFileType(self):
2885 """
2886 If the file type passed to :py:obj:`load_certificate_request` is
2887 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2888 :py:class:`ValueError` is raised.
2889 """
Alex Gaynor7778e792016-07-03 23:38:48 -04002890 with pytest.raises(ValueError):
2891 load_certificate_request(object(), b"")
2892 with pytest.raises(ValueError):
2893 load_certificate(object(), b"")
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002894
Alex Gaynor37726112016-07-04 09:51:32 -04002895 def test_bad_certificate(self):
2896 """
2897 If the bytes passed to :obj:`load_certificate` are not a valid
2898 certificate, an exception is raised.
2899 """
2900 with pytest.raises(Error):
2901 load_certificate(FILETYPE_ASN1, b"lol")
2902
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002903
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002904class PKCS7Tests(TestCase):
2905 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002906 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002907 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002908
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002909 def test_type(self):
2910 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002911 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002912 """
2913 self.assertTrue(isinstance(PKCS7Type, type))
2914 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2915
2916 # XXX This doesn't currently work.
2917 # self.assertIdentical(PKCS7, PKCS7Type)
2918
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002919 # XXX Opposite results for all these following methods
2920
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002921 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002922 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002923 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2924 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002925 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002926 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2927 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2928
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002929 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002930 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002931 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2932 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002933 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002934 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2935 self.assertTrue(pkcs7.type_is_signed())
2936
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002937 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002938 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002939 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2940 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002941 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002942 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2943 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2944
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002945 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002946 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002947 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2948 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002949 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002950 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2951 self.assertFalse(pkcs7.type_is_enveloped())
2952
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002953 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002954 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002955 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2956 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002957 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002958 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2959 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2960
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002961 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002962 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002963 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2964 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002965 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002966 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2967 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2968
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002969 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002970 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002971 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2972 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002973 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002974 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2975 self.assertFalse(pkcs7.type_is_data())
2976
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002977 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002978 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002979 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2980 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002981 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002982 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2983 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2984
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002985 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002986 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002987 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2988 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002989 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002990 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2991 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2992
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002993 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002994 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002995 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2996 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002997 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002998 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002999 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003000
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003001 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003002 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003003 If an attribute other than one of the methods tested here is accessed
3004 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
3005 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003006 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003007 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3008 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
3009
3010
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003011class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003012 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003013 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003014 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003015
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003016 def signable(self):
3017 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003018 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003019 """
3020 return NetscapeSPKI()
3021
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003022 def test_type(self):
3023 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003024 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
3025 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003026 """
3027 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
3028 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
3029
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003030 def test_construction(self):
3031 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003032 :py:obj:`NetscapeSPKI` returns an instance of
3033 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003034 """
3035 nspki = NetscapeSPKI()
3036 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
3037
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003038 def test_invalid_attribute(self):
3039 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003040 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
3041 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003042 """
3043 nspki = NetscapeSPKI()
3044 self.assertRaises(AttributeError, lambda: nspki.foo)
3045
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003046 def test_b64_encode(self):
3047 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003048 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
3049 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003050 """
3051 nspki = NetscapeSPKI()
3052 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003053 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003054
3055
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003056class TestRevoked(object):
3057 """
3058 Please add test cases for the Revoked class here if possible. This class
3059 holds the new py.test style tests.
3060 """
3061 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3062 """
3063 The get_reason method on the Revoked class checks to see if the
3064 extension is NID_crl_reason and should skip it otherwise. This test
3065 loads a CRL with extensions it should ignore.
3066 """
3067 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3068 revoked = crl.get_revoked()
3069 reason = revoked[1].get_reason()
3070 assert reason == b'Unspecified'
3071
3072 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3073 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3074 revoked = crl.get_revoked()
3075 revoked[1].set_reason(None)
3076 reason = revoked[1].get_reason()
3077 assert reason is None
3078
3079
Rick Dean536ba022009-07-24 23:57:27 -05003080class RevokedTests(TestCase):
3081 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003082 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3083 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003084 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003085
Rick Dean536ba022009-07-24 23:57:27 -05003086 def test_construction(self):
3087 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003088 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003089 that it is empty.
3090 """
3091 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003092 self.assertTrue(isinstance(revoked, Revoked))
3093 self.assertEquals(type(revoked), Revoked)
3094 self.assertEquals(revoked.get_serial(), b('00'))
3095 self.assertEquals(revoked.get_rev_date(), None)
3096 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003097
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003098 def test_construction_wrong_args(self):
3099 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003100 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3101 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003102 """
3103 self.assertRaises(TypeError, Revoked, None)
3104 self.assertRaises(TypeError, Revoked, 1)
3105 self.assertRaises(TypeError, Revoked, "foo")
3106
Rick Dean536ba022009-07-24 23:57:27 -05003107 def test_serial(self):
3108 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003109 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003110 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003111 with grace.
3112 """
3113 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003114 ret = revoked.set_serial(b('10b'))
3115 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003116 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003117 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003118
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003119 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003120 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003121 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003122
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003123 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003124 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003125 self.assertRaises(TypeError, revoked.get_serial, 1)
3126 self.assertRaises(TypeError, revoked.get_serial, None)
3127 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003128
Rick Dean536ba022009-07-24 23:57:27 -05003129 def test_date(self):
3130 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003131 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003132 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003133 with grace.
3134 """
3135 revoked = Revoked()
3136 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003137 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003138
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003139 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003140 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003141 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003142 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003143 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003144
Rick Dean6385faf2009-07-26 00:07:47 -05003145 def test_reason(self):
3146 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003147 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003148 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003149 as "set". Likewise, each reason of all_reasons() must work.
3150 """
3151 revoked = Revoked()
3152 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003153 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003154 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003155 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003156 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003157 self.assertEquals(
3158 reason.lower().replace(b(' '), b('')),
3159 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003160 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003161
3162 revoked.set_reason(None)
3163 self.assertEqual(revoked.get_reason(), None)
3164
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003165 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003166 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003167 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003168 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003169 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003170 """
3171 revoked = Revoked()
3172 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003173 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003174
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003175 def test_get_reason_wrong_arguments(self):
3176 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003177 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3178 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003179 """
3180 revoked = Revoked()
3181 self.assertRaises(TypeError, revoked.get_reason, None)
3182 self.assertRaises(TypeError, revoked.get_reason, 1)
3183 self.assertRaises(TypeError, revoked.get_reason, "foo")
3184
3185
Rick Dean536ba022009-07-24 23:57:27 -05003186class CRLTests(TestCase):
3187 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003188 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003189 """
3190 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3191 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3192
Dan Sully44e767a2016-06-04 18:05:27 -07003193 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3194 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3195 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3196 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3197 intermediate_server_cert = load_certificate(
3198 FILETYPE_PEM, intermediate_server_cert_pem)
3199 intermediate_server_key = load_privatekey(
3200 FILETYPE_PEM, intermediate_server_key_pem)
3201
Rick Dean536ba022009-07-24 23:57:27 -05003202 def test_construction(self):
3203 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003204 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003205 that it is empty
3206 """
3207 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003208 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003209 self.assertEqual(crl.get_revoked(), None)
3210
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003211 def test_construction_wrong_args(self):
3212 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003213 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3214 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003215 """
3216 self.assertRaises(TypeError, CRL, 1)
3217 self.assertRaises(TypeError, CRL, "")
3218 self.assertRaises(TypeError, CRL, None)
3219
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003220 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003221 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003222 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003223 """
3224 crl = CRL()
3225 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003226 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003227 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003228 revoked.set_serial(b('3ab'))
3229 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003230 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003231 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003232
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003233 def test_export_pem(self):
3234 """
3235 If not passed a format, ``CRL.export`` returns a "PEM" format string
3236 representing a serial number, a revoked reason, and certificate issuer
3237 information.
3238 """
3239 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003240 # PEM format
3241 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003242 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003243
3244 # These magic values are based on the way the CRL above was constructed
3245 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003246 text.index(b('Serial Number: 03AB'))
3247 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003248 text.index(
3249 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3250 )
3251
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003252 def test_export_der(self):
3253 """
3254 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3255 "DER" format string representing a serial number, a revoked reason, and
3256 certificate issuer information.
3257 """
3258 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003259
3260 # DER format
3261 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003262 text = _runopenssl(
3263 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3264 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003265 text.index(b('Serial Number: 03AB'))
3266 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003267 text.index(
3268 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3269 )
3270
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003271 def test_export_text(self):
3272 """
3273 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3274 text format string like the one produced by the openssl command line
3275 tool.
3276 """
3277 crl = self._get_crl()
3278
3279 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3280 text = _runopenssl(
3281 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3282 )
Rick Dean536ba022009-07-24 23:57:27 -05003283
3284 # text format
3285 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3286 self.assertEqual(text, dumped_text)
3287
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003288 def test_export_custom_digest(self):
3289 """
3290 If passed the name of a digest function, ``CRL.export`` uses a
3291 signature algorithm based on that digest function.
3292 """
3293 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003294 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003295 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3296 text.index(b('Signature Algorithm: sha1'))
3297
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003298 def test_export_md5_digest(self):
3299 """
3300 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3301 not emit a deprecation warning.
3302 """
3303 crl = self._get_crl()
3304 with catch_warnings(record=True) as catcher:
3305 simplefilter("always")
3306 self.assertEqual(0, len(catcher))
3307 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3308 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3309 text.index(b('Signature Algorithm: md5'))
3310
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003311 def test_export_default_digest(self):
3312 """
3313 If not passed the name of a digest function, ``CRL.export`` uses a
3314 signature algorithm based on MD5 and emits a deprecation warning.
3315 """
3316 crl = self._get_crl()
3317 with catch_warnings(record=True) as catcher:
3318 simplefilter("always")
3319 dumped_crl = crl.export(self.cert, self.pkey)
3320 self.assertEqual(
3321 "The default message digest (md5) is deprecated. "
3322 "Pass the name of a message digest explicitly.",
3323 str(catcher[0].message),
3324 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003325 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3326 text.index(b('Signature Algorithm: md5'))
3327
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003328 def test_export_invalid(self):
3329 """
3330 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003331 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003332 """
3333 crl = CRL()
3334 self.assertRaises(Error, crl.export, X509(), PKey())
3335
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003336 def test_add_revoked_keyword(self):
3337 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003338 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003339 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003340 """
3341 crl = CRL()
3342 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003343 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003344 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003345 crl.add_revoked(revoked=revoked)
3346 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3347
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003348 def test_export_wrong_args(self):
3349 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003350 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003351 four arguments, or with arguments other than the certificate,
3352 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003353 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003354 """
3355 crl = CRL()
3356 self.assertRaises(TypeError, crl.export)
3357 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003358 with pytest.raises(TypeError):
3359 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3360 with pytest.raises(TypeError):
3361 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3362 with pytest.raises(TypeError):
3363 crl.export(self.cert, None, FILETYPE_PEM, 10)
3364 with pytest.raises(TypeError):
3365 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003366 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3367
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003368 def test_export_unknown_filetype(self):
3369 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003370 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003371 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3372 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003373 """
3374 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003375 with pytest.raises(ValueError):
3376 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003377
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003378 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003379 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003380 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003381 in a :py:obj:`ValueError` being raised.
3382 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003383 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003384 self.assertRaises(
3385 ValueError,
3386 crl.export,
3387 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3388 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003389
Rick Dean536ba022009-07-24 23:57:27 -05003390 def test_get_revoked(self):
3391 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003392 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003393 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3394 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003395 """
3396 crl = CRL()
3397
3398 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003399 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003400 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003401 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003402 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003403 revoked.set_serial(b('100'))
3404 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003405 crl.add_revoked(revoked)
3406
3407 revs = crl.get_revoked()
3408 self.assertEqual(len(revs), 2)
3409 self.assertEqual(type(revs[0]), Revoked)
3410 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003411 self.assertEqual(revs[0].get_serial(), b('03AB'))
3412 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003413 self.assertEqual(revs[0].get_rev_date(), now)
3414 self.assertEqual(revs[1].get_rev_date(), now)
3415
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003416 def test_get_revoked_wrong_args(self):
3417 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003418 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3419 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003420 """
3421 crl = CRL()
3422 self.assertRaises(TypeError, crl.get_revoked, None)
3423 self.assertRaises(TypeError, crl.get_revoked, 1)
3424 self.assertRaises(TypeError, crl.get_revoked, "")
3425 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3426
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003427 def test_add_revoked_wrong_args(self):
3428 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003429 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3430 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003431 """
3432 crl = CRL()
3433 self.assertRaises(TypeError, crl.add_revoked)
3434 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3435 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3436
Rick Dean536ba022009-07-24 23:57:27 -05003437 def test_load_crl(self):
3438 """
3439 Load a known CRL and inspect its revocations. Both
3440 PEM and DER formats are loaded.
3441 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003442 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003443 revs = crl.get_revoked()
3444 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003445 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003446 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003447 self.assertEqual(revs[1].get_serial(), b('0100'))
3448 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003449
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003450 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003451 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003452 revs = crl.get_revoked()
3453 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003454 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003455 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003456 self.assertEqual(revs[1].get_serial(), b('0100'))
3457 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003458
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003459 def test_load_crl_wrong_args(self):
3460 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003461 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3462 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003463 """
3464 self.assertRaises(TypeError, load_crl)
3465 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3466 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3467
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003468 def test_load_crl_bad_filetype(self):
3469 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003470 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3471 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003472 """
3473 self.assertRaises(ValueError, load_crl, 100, crlData)
3474
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003475 def test_load_crl_bad_data(self):
3476 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003477 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3478 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003479 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003480 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003481
Dan Sully44e767a2016-06-04 18:05:27 -07003482 def test_get_issuer(self):
3483 """
3484 Load a known CRL and assert its issuer's common name is
3485 what we expect from the encoded crlData string.
3486 """
3487 crl = load_crl(FILETYPE_PEM, crlData)
3488 self.assertTrue(isinstance(crl.get_issuer(), X509Name))
3489 self.assertEqual(crl.get_issuer().CN, 'Testing Root CA')
3490
Dominic Chenf05b2122015-10-13 16:32:35 +00003491 def test_dump_crl(self):
3492 """
3493 The dumped CRL matches the original input.
3494 """
3495 crl = load_crl(FILETYPE_PEM, crlData)
3496 buf = dump_crl(FILETYPE_PEM, crl)
3497 assert buf == crlData
3498
Dan Sully44e767a2016-06-04 18:05:27 -07003499 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3500 """
3501 Create a CRL.
3502
3503 :param list[X509] certs: A list of certificates to revoke.
3504 :rtype: CRL
3505 """
3506 crl = CRL()
3507 for cert in certs:
3508 revoked = Revoked()
3509 # FIXME: This string splicing is an unfortunate implementation
3510 # detail that has been reported in
3511 # https://github.com/pyca/pyopenssl/issues/258
3512 serial = hex(cert.get_serial_number())[2:].encode('utf-8')
3513 revoked.set_serial(serial)
3514 revoked.set_reason(b'unspecified')
3515 revoked.set_rev_date(b'20140601000000Z')
3516 crl.add_revoked(revoked)
3517 crl.set_version(1)
3518 crl.set_lastUpdate(b'20140601000000Z')
3519 crl.set_nextUpdate(b'20180601000000Z')
3520 crl.sign(issuer_cert, issuer_key, digest=b'sha512')
3521 return crl
3522
3523 def test_verify_with_revoked(self):
3524 """
3525 :func:`verify_certificate` raises error when an intermediate
3526 certificate is revoked.
3527 """
3528 store = X509Store()
3529 store.add_cert(self.root_cert)
3530 store.add_cert(self.intermediate_cert)
3531 root_crl = self._make_test_crl(
3532 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3533 intermediate_crl = self._make_test_crl(
3534 self.intermediate_cert, self.intermediate_key, certs=[])
3535 store.add_crl(root_crl)
3536 store.add_crl(intermediate_crl)
3537 store.set_flags(
3538 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3539 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3540 e = self.assertRaises(
3541 X509StoreContextError, store_ctx.verify_certificate)
3542 self.assertEqual(e.args[0][2], 'certificate revoked')
3543
3544 def test_verify_with_missing_crl(self):
3545 """
3546 :func:`verify_certificate` raises error when an intermediate
3547 certificate's CRL is missing.
3548 """
3549 store = X509Store()
3550 store.add_cert(self.root_cert)
3551 store.add_cert(self.intermediate_cert)
3552 root_crl = self._make_test_crl(
3553 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3554 store.add_crl(root_crl)
3555 store.set_flags(
3556 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3557 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3558 e = self.assertRaises(
3559 X509StoreContextError, store_ctx.verify_certificate)
3560 self.assertEqual(e.args[0][2], 'unable to get certificate CRL')
3561 self.assertEqual(
3562 e.certificate.get_subject().CN, 'intermediate-service')
3563
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003564
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003565class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003566 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003567 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003568 """
3569 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3570 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003571 intermediate_server_cert = load_certificate(
3572 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003573
3574 def test_valid(self):
3575 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003576 :py:obj:`verify_certificate` returns ``None`` when called with a
3577 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003578 """
3579 store = X509Store()
3580 store.add_cert(self.root_cert)
3581 store.add_cert(self.intermediate_cert)
3582 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003583 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003584
3585 def test_reuse(self):
3586 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003587 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003588 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003589 """
3590 store = X509Store()
3591 store.add_cert(self.root_cert)
3592 store.add_cert(self.intermediate_cert)
3593 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003594 self.assertEqual(store_ctx.verify_certificate(), None)
3595 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003596
3597 def test_trusted_self_signed(self):
3598 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003599 :py:obj:`verify_certificate` returns ``None`` when called with a
3600 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003601 """
3602 store = X509Store()
3603 store.add_cert(self.root_cert)
3604 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003605 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003606
3607 def test_untrusted_self_signed(self):
3608 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003609 :py:obj:`verify_certificate` raises error when a self-signed
3610 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003611 """
3612 store = X509Store()
3613 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003614 with pytest.raises(X509StoreContextError) as exc:
3615 store_ctx.verify_certificate()
3616
3617 assert exc.value.args[0][2] == 'self signed certificate'
3618 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003619
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003620 def test_invalid_chain_no_root(self):
3621 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003622 :py:obj:`verify_certificate` raises error when a root certificate is
3623 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003624 """
3625 store = X509Store()
3626 store.add_cert(self.intermediate_cert)
3627 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003628
3629 with pytest.raises(X509StoreContextError) as exc:
3630 store_ctx.verify_certificate()
3631
3632 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3633 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003634
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003635 def test_invalid_chain_no_intermediate(self):
3636 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003637 :py:obj:`verify_certificate` raises error when an intermediate
3638 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003639 """
3640 store = X509Store()
3641 store.add_cert(self.root_cert)
3642 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003643
Alex Gaynor85b49702015-09-05 16:30:59 -04003644 with pytest.raises(X509StoreContextError) as exc:
3645 store_ctx.verify_certificate()
3646
3647 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3648 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003649
Stephen Holsapple46a09252015-02-12 14:45:43 -08003650 def test_modification_pre_verify(self):
3651 """
3652 :py:obj:`verify_certificate` can use a store context modified after
3653 instantiation.
3654 """
3655 store_bad = X509Store()
3656 store_bad.add_cert(self.intermediate_cert)
3657 store_good = X509Store()
3658 store_good.add_cert(self.root_cert)
3659 store_good.add_cert(self.intermediate_cert)
3660 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003661
3662 with pytest.raises(X509StoreContextError) as exc:
3663 store_ctx.verify_certificate()
3664
3665 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3666 assert exc.value.certificate.get_subject().CN == 'intermediate'
3667
Stephen Holsapple46a09252015-02-12 14:45:43 -08003668 store_ctx.set_store(store_good)
3669 self.assertEqual(store_ctx.verify_certificate(), None)
3670
3671
James Yonan7c2e5d32010-02-27 05:45:50 -07003672class SignVerifyTests(TestCase):
3673 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003674 Tests for :py:obj:`OpenSSL.crypto.sign` and
3675 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003676 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003677
James Yonan7c2e5d32010-02-27 05:45:50 -07003678 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003679 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003680 :py:obj:`sign` generates a cryptographic signature which
3681 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003682 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003683 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003684 "It was a bright cold day in April, and the clocks were striking "
3685 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3686 "effort to escape the vile wind, slipped quickly through the "
3687 "glass doors of Victory Mansions, though not quickly enough to "
3688 "prevent a swirl of gritty dust from entering along with him.")
3689
3690 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003691 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003692 # verify the content with this cert
3693 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3694 # certificate unrelated to priv_key, used to trigger an error
3695 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003696
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003697 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003698 sig = sign(priv_key, content, digest)
3699
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003700 # Verify the signature of content, will throw an exception if
3701 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003702 verify(good_cert, sig, content, digest)
3703
3704 # This should fail because the certificate doesn't match the
3705 # private key that was used to sign the content.
3706 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3707
3708 # This should fail because we've "tainted" the content after
3709 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003710 self.assertRaises(
3711 Error, verify,
3712 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003713
3714 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003715 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003716 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003717 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003718 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003719
Abraham Martinc5484ba2015-03-25 15:33:05 +00003720 def test_sign_verify_with_text(self):
3721 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003722 :py:obj:`sign` generates a cryptographic signature which
3723 :py:obj:`verify` can check. Deprecation warnings raised because using
3724 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003725 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003726 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003727 b"It was a bright cold day in April, and the clocks were striking "
3728 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3729 b"effort to escape the vile wind, slipped quickly through the "
3730 b"glass doors of Victory Mansions, though not quickly enough to "
3731 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003732 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003733
3734 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3735 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3736 for digest in ['md5', 'sha1']:
3737 with catch_warnings(record=True) as w:
3738 simplefilter("always")
3739 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003740
3741 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003742 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003743 WARNING_TYPE_EXPECTED
3744 ),
3745 str(w[-1].message)
3746 )
3747 self.assertIs(w[-1].category, DeprecationWarning)
3748
Abraham Martinc5484ba2015-03-25 15:33:05 +00003749 with catch_warnings(record=True) as w:
3750 simplefilter("always")
3751 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003752
3753 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003754 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003755 WARNING_TYPE_EXPECTED
3756 ),
3757 str(w[-1].message)
3758 )
3759 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003760
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003761 def test_sign_nulls(self):
3762 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003763 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003764 """
3765 content = b("Watch out! \0 Did you see it?")
3766 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3767 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3768 sig = sign(priv_key, content, "sha1")
3769 verify(good_cert, sig, content, "sha1")
3770
Colleen Murphye09399b2016-03-01 17:40:49 -08003771 def test_sign_with_large_key(self):
3772 """
3773 :py:obj:`sign` produces a signature for a string when using a long key.
3774 """
3775 content = b(
3776 "It was a bright cold day in April, and the clocks were striking "
3777 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3778 "effort to escape the vile wind, slipped quickly through the "
3779 "glass doors of Victory Mansions, though not quickly enough to "
3780 "prevent a swirl of gritty dust from entering along with him.")
3781
3782 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3783 sign(priv_key, content, "sha1")
3784
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003785
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003786class EllipticCurveTests(TestCase):
3787 """
3788 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3789 :py:obj:`get_elliptic_curves`.
3790 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003791
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003792 def test_set(self):
3793 """
3794 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3795 """
3796 self.assertIsInstance(get_elliptic_curves(), set)
3797
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003798 def test_some_curves(self):
3799 """
3800 If :py:mod:`cryptography` has elliptic curve support then the set
3801 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3802 it.
3803
3804 There could be an OpenSSL that violates this assumption. If so, this
3805 test will fail and we'll find out.
3806 """
3807 curves = get_elliptic_curves()
3808 if lib.Cryptography_HAS_EC:
3809 self.assertTrue(curves)
3810 else:
3811 self.assertFalse(curves)
3812
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003813 def test_a_curve(self):
3814 """
3815 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3816 supported curve.
3817 """
3818 curves = get_elliptic_curves()
3819 if curves:
3820 curve = next(iter(curves))
3821 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3822 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003823 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003824
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003825 def test_not_a_curve(self):
3826 """
3827 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3828 with a name which does not identify a supported curve.
3829 """
3830 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003831 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003832
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003833 def test_repr(self):
3834 """
3835 The string representation of a curve object includes simply states the
3836 object is a curve and what its name is.
3837 """
3838 curves = get_elliptic_curves()
3839 if curves:
3840 curve = next(iter(curves))
3841 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3842
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003843 def test_to_EC_KEY(self):
3844 """
3845 The curve object can export a version of itself as an EC_KEY* via the
3846 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3847 """
3848 curves = get_elliptic_curves()
3849 if curves:
3850 curve = next(iter(curves))
3851 # It's not easy to assert anything about this object. However, see
3852 # leakcheck/crypto.py for a test that demonstrates it at least does
3853 # not leak memory.
3854 curve._to_EC_KEY()
3855
3856
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003857class EllipticCurveFactory(object):
3858 """
3859 A helper to get the names of two curves.
3860 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003861
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003862 def __init__(self):
3863 curves = iter(get_elliptic_curves())
3864 try:
3865 self.curve_name = next(curves).name
3866 self.another_curve_name = next(curves).name
3867 except StopIteration:
3868 self.curve_name = self.another_curve_name = None
3869
3870
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003871class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3872 """
3873 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3874 """
3875 curve_factory = EllipticCurveFactory()
3876
3877 if curve_factory.curve_name is None:
3878 skip = "There are no curves available there can be no curve objects."
3879
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003880 def anInstance(self):
3881 """
3882 Get the curve object for an arbitrary curve supported by the system.
3883 """
3884 return get_elliptic_curve(self.curve_factory.curve_name)
3885
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003886 def anotherInstance(self):
3887 """
3888 Get the curve object for an arbitrary curve supported by the system -
3889 but not the one returned by C{anInstance}.
3890 """
3891 return get_elliptic_curve(self.curve_factory.another_curve_name)
3892
3893
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003894class EllipticCurveHashTests(TestCase):
3895 """
3896 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3897 as an item in a :py:type:`dict` or :py:type:`set`).
3898 """
3899 curve_factory = EllipticCurveFactory()
3900
3901 if curve_factory.curve_name is None:
3902 skip = "There are no curves available there can be no curve objects."
3903
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003904 def test_contains(self):
3905 """
3906 The ``in`` operator reports that a :py:type:`set` containing a curve
3907 does contain that curve.
3908 """
3909 curve = get_elliptic_curve(self.curve_factory.curve_name)
3910 curves = set([curve])
3911 self.assertIn(curve, curves)
3912
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003913 def test_does_not_contain(self):
3914 """
3915 The ``in`` operator reports that a :py:type:`set` not containing a
3916 curve does not contain that curve.
3917 """
3918 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003919 curves = set([
3920 get_elliptic_curve(self.curve_factory.another_curve_name)
3921 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003922 self.assertNotIn(curve, curves)
3923
3924
Rick Dean5b7b6372009-04-01 11:34:06 -05003925if __name__ == '__main__':
3926 main()