blob: 136af0a04ac6535b29ca58ee7c630663841eed16 [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 (
24 X509Store, X509StoreType, X509StoreContext, X509StoreContextError
25)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070026from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -050027from OpenSSL.crypto import X509Extension, X509ExtensionType
Rick Dean5b7b6372009-04-01 11:34:06 -050028from OpenSSL.crypto import load_certificate, load_privatekey
Cory Benfield6492f7c2015-10-27 16:57:58 +090029from OpenSSL.crypto import load_publickey, dump_publickey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040030from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040031from OpenSSL.crypto import dump_certificate, load_certificate_request
32from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040033from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Jean-Paul Calderone9178ee62010-01-25 17:55:30 -050034from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000035from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040036from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040037from OpenSSL.crypto import (
38 sign, verify, get_elliptic_curve, get_elliptic_curves)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020039from OpenSSL._util import native, lib
40
41from .util import (
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040042 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
43)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040044
Alex Gaynoraceb3e22015-09-05 12:00:22 -040045
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040046def normalize_certificate_pem(pem):
47 return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
48
49
50def normalize_privatekey_pem(pem):
51 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
52
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040053
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050054GOOD_CIPHER = "blowfish"
55BAD_CIPHER = "zippers"
56
Anthony Alba2ce737f2015-12-04 11:04:56 +080057GOOD_DIGEST = "SHA1"
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050058BAD_DIGEST = "monkeys"
59
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040060root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050061MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
62BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
63ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
64NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
65MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
66ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
67urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
682xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
691dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
70FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
71VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
72BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
73b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
74AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
75hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
76w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
77-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040078""")
Rick Dean94e46fd2009-07-18 14:51:24 -050079
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040080root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050081MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
82jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
833claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
84AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
85yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
866JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
87BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
88u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
89PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
90I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
91ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
926AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
93cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
94-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040095""")
Rick Dean94e46fd2009-07-18 14:51:24 -050096
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070097intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
98MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
99WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
100DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
101ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
102dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
103MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
104AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
105FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
10621H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
107AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
108QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1099n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1109mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
111-----END CERTIFICATE-----
112""")
113
114intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
115MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
116ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
117qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
118AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
119rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
120147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
121+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
122wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
123sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
12452vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
125DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
126/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
127NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
128-----END RSA PRIVATE KEY-----
129""")
130
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400131server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500132MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
133BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
134VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
135NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
136gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
137lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
138b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
139lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
140gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
141dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1422mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
143uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
144-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400145""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500146
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400147server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500148MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
149U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
150SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
151AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
152j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
153j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
154Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
155msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
156FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1574e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1581sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
159NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
160r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
161-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400162"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500163
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700164intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
165MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
166ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
167CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
168biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
169BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
170CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
171biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
172iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
173+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
174biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
175UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1763bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
177x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
178-----END CERTIFICATE-----
179""")
180
181intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
182MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
183SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1848Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
185AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1865ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
187d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
188z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
189dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
190EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
191X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
1929UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
193ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
194nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
195-----END RSA PRIVATE KEY-----
196""")
197
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400198client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500199MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
200BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
201VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
202ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
203MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
204rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
205iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
206oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2070fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
208Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2099Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
210PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
211-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400212""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500213
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400214client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500215MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
216btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
217eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
218AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
219zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
220h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
221V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
222TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
223dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
224D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
225si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
226JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
227f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
228-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400229"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400230
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400231cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400232MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
233BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
234ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
235NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
236MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
237ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
238urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2392xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2401dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
241FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
242VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
243BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
244b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
245AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
246hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
247w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
248-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400249""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400250
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400251cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
252-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400253MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
254jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2553claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
256AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
257yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2586JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
259BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
260u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
261PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
262I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
263ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2646AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
265cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
266-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400267"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400268
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400269cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
270MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
271EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
272ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
273BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
274E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
275xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
276gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
277Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
278oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
279-----END CERTIFICATE REQUEST-----
280""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500281
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400282encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400283Proc-Type: 4,ENCRYPTED
284DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400285
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400286SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
287a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2888+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
289mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
290+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
291fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
292tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
293rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
294gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
295o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
2967SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
297MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
29811n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
299-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400300""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400301
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400302encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400303
Cory Benfield6492f7c2015-10-27 16:57:58 +0900304
305cleartextPublicKeyPEM = b("""-----BEGIN PUBLIC KEY-----
306MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
307gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
30890qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
309ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
310XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
3118Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
312ywIDAQAB
313-----END PUBLIC KEY-----
314""")
315
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400316# Some PKCS#7 stuff. Generated with the openssl command line:
317#
318# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
319#
320# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400321pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400322-----BEGIN PKCS7-----
323MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
324BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
325A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
326MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
327cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
328A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
329HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
330SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
331zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
332LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
333A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
33465w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
335Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
336Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
337bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
338VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
339/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
340Ho4EzbYCOaEAMQA=
341-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400342""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400343
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700344pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700345MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
346BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
347A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
348MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
349cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
350A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
351HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
352SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
353zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
354LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
355A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
35665w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
357Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
358Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
359bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
360VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
361/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
362Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700363""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700364
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400365crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500366-----BEGIN X509 CRL-----
367MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
368SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
369D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
370MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
371MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3724dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3730yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
374vrzEeLDRiiPl92dyyWmu
375-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400376""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400377
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400378crlDataUnsupportedExtension = b("""\
379-----BEGIN X509 CRL-----
380MIIGRzCCBS8CAQIwDQYJKoZIhvcNAQELBQAwJzELMAkGA1UEBhMCVVMxGDAWBgNV
381BAMMD2NyeXB0b2dyYXBoeS5pbxgPMjAxNTAxMDEwMDAwMDBaGA8yMDE2MDEwMTAw
382MDAwMFowggTOMBQCAQAYDzIwMTUwMTAxMDAwMDAwWjByAgEBGA8yMDE1MDEwMTAw
383MDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAn
384MQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQD
385CgEAMHICAQIYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAw
386MDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlw
387dG9ncmFwaHkuaW8wCgYDVR0VBAMKAQEwcgIBAxgPMjAxNTAxMDEwMDAwMDBaMFww
388GAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTArpCkwJzELMAkGA1UE
389BhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNVHRUEAwoBAjByAgEE
390GA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQG
391A1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5
392LmlvMAoGA1UdFQQDCgEDMHICAQUYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQR
393GA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgw
394FgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQQwcgIBBhgPMjAxNTAx
395MDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTAr
396pCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNV
397HRUEAwoBBTByAgEHGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAx
398MDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwP
399Y3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEGMHICAQgYDzIwMTUwMTAxMDAwMDAw
400WjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJ
401BgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQgw
402cgIBCRgPMjAxNTAxMDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAw
403WjA0BgNVHR0ELTArpCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dy
404YXBoeS5pbzAKBgNVHRUEAwoBCTByAgEKGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNV
405HRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJV
406UzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEKMC4CAQsYDzIw
407MTUwMTAxMDAwMDAwWjAYMAoGA1UdFQQDCgEBMAoGAyoDBAQDCgEAMA0GCSqGSIb3
408DQEBCwUAA4IBAQBTaloHlPaCZzYee8LxkWej5meiqxQVNWFoVdjesroa+f1FRrH+
409drRU60Nq97KCKf7f9GNN/J3ZIlQmYhmuDqh12f+XLpotoj1ZRfBz2hjFCkJlv+2c
410oWWGNHgA70ndFoVtcmX088SYpX8E3ARATivS4q2h9WlwV6rO93mhg3HGIe3JpcK4
4117BcW6Poi/ut/zsDOkVbI00SqaujRpdmdCTht82MH3ztjyDkI9KYaD/YEweKSrWOz
412SdEILd164bfBeLuplVI+xpmTEMVNpXBlSXl7+xIw9Vk7p7Q1Pa3k/SvhOldYCm6y
413C1xAg/AAq6w78yzYt18j5Mj0s6eeHi1YpHKw
414-----END X509 CRL-----
415""")
416
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400417
418# A broken RSA private key which can be used to test the error path through
419# PKey.check.
420inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
421MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
4225kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
423OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
424zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
425nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
426HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
427oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
428-----END RSA PRIVATE KEY-----
429""")
430
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400431# certificate with NULL bytes in subjectAltName and common name
432
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400433nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400434MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
435DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
436eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
437RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
438ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
439NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
440DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
441ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
442ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
443hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
444BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
445pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
446vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
447KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
448oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
44908LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
450HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
451BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
452Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
453bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
454AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
455i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
456HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
457kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
458VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
459RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
460-----END CERTIFICATE-----""")
461
Colleen Murphye09399b2016-03-01 17:40:49 -0800462large_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
463MIIJYgIBAAKCAg4AtRua8eIeevRfsj+fkcHr1vmse7Kgb+oX1ssJAvCb1R7JQMnH
464hNDjDP6b3vEkZuPUzlDHymP+cNkXvvi4wJ4miVbO3+SeU4Sh+jmsHeHzGIXat9xW
4659PFtuPM5FQq8zvkY8aDeRYmYwN9JKu4/neMBCBqostYlTEWg+bSytO/qWnyHTHKh
466g0GfaDdqUQPsGQw+J0MgaYIjQOCVASHAPlzbDQLCtuOb587rwTLkZA2GwoHB/LyJ
467BwT0HHgBaiObE12Vs6wi2en0Uu11CiwEuK1KIBcZ2XbE6eApaZa6VH9ysEmUxPt7
468TqyZ4E2oMIYaLPNRxuvozdwTlj1svI1k1FrkaXGc5MTjbgigPMKjIb0T7b/4GNzt
469DhP1LvAeUMnrEi3hJJrcJPXHPqS8/RiytR9xQQW6Sdh4LaA3f9MQm3WSevWage3G
470P8YcCLssOVKsArDjuA52NF5LmYuAeUzXprm4ITDi2oO+0iFBpFW6VPEK4A9vO0Yk
471M/6Wt6tG8zyWhaSH1zFUTwfQ9Yvjyt5w1lrUaAJuoTpwbMVZaDJaEhjOaXU0dyPQ
472jOsePDOQcU6dkeTWsQ3LsHPEEug/X6819TLG5mb3V7bvV9nPFBfTJSCEG794kr90
473XgZfIN71FrdByxLerlbuJI21pPs/nZi9SXi9jAWeiS45/azUxMsyYgJArui+gjq7
474sV1pWiBm6/orAgMBAAECggINQp5L6Yu+oIXBqcSjgq8tfF9M5hd30pLuf/EheHZf
475LA7uAqn2fVGFI2OInIJhXIOT5OxsAXO0xXfltzawZxIFpOFMqajj4F7aYjvSpw9V
476J4EdSiJ/zgv8y1qUdbwEZbHVThRZjoSlrtSzilonBoHZAE0mHtqMz7iRFSk1zz6t
477GunRrvo/lROPentf3TsvHquVNUYI5yaapyO1S7xJhecMIIYSb8nbsHI54FBDGNas
4786mFmpPwI/47/6HTwOEWupnn3NicsjrHzUInOUpaMig4cRR+aP5bjqg/ty8xI8AoN
479evEmCytiWTc+Rvbp1ieN+1jpjN18PjUk80/W7qioHUDt4ieLic8uxWH2VD9SCEnX
480Mpi9tA/FqoZ+2A/3m1OfrY6jiZVE2g+asi9lCK7QVWL39eK82H4rPvtp0/dyo1/i
481ZZz68TXg+m8IgEZcp88hngbkuoTTzpGE73QuPKhGA1uMIimDdqPPB5WP76q+03Oi
482IRR5DfZnqPERed49by0enJ7tKa/gFPZizOV8ALKr0Dp+vfAkxGDLPLBLd2A3//tw
483xg0Q/wltihHSBujv4nYlDXdc5oYyMYZ+Lhc/VuOghHfBq3tgEQ1ECM/ofqXEIdy7
484nVcpZn3Eeq8Jl5CrqxE1ee3NxlzsJHn99yGQpr7mOhW/psJF3XNz80Meg3L4m1T8
485sMBK0GbaassuJhdzb5whAoIBBw48sx1b1WR4XxQc5O/HjHva+l16i2pjUnOUTcDF
486RWmSbIhBm2QQ2rVhO8+fak0tkl6ZnMWW4i0U/X5LOEBbC7+IS8bO3j3Revi+Vw5x
487j96LMlIe9XEub5i/saEWgiz7maCvfzLFU08e1OpT4qPDpP293V400ubA6R7WQTCv
488pBkskGwHeu0l/TuKkVqBFFUTu7KEbps8Gjg7MkJaFriAOv1zis/umK8pVS3ZAM6e
4898w5jfpRccn8Xzta2fRwTB5kCmfxdDsY0oYGxPLRAbW72bORoLGuyyPp/ojeGwoik
490JX9RttErc6FjyZtks370Pa8UL5QskyhMbDhrZW2jFD+RXYM1BrvmZRjbAoIBBwy4
491iFJpuDfytJfz1MWtaL5DqEL/kmiZYAXl6hifNhGu5GAipVIIGsDqEYW4i+VC15aa
4927kOCwz/I5zsB3vSDW96IRs4wXtqEZSibc2W/bqfVi+xcvPPl1ZhQ2EAwa4D/x035
493kyf20ffWOU+1yf2cnijzqs3IzlveUm+meLw5s3Rc+iG7DPWWeCoe1hVwANI1euNc
494pqKwKY905yFyjOje2OgiEU2kS4YME4zGeBys8yo7E42hNnN2EPK6xkkUqzdudLLQ
4958OUlKRTc8AbIf3XG1rpA4VUpTv3hhxGGwCRy6If8zgZQsNYchgNztRGk72Gcb8Dm
496vFSEN3ZtwxU64G3YZzntdcr2WPzxAoIBBw30g6Fgdb/gmVnOpL0//T0ePNDKIMPs
497jVJLaRduhoZgB1Bb9qPUPX0SzRzLZtg1tkZSDjBDoHmOHJfhxUaXt+FLCPPbrE4t
498+nq9n/nBaMM779w9ClqhqLOyGrwKoxjSmhi+TVEHyIxCbXMvPHVHfX9WzxjbcGrN
499ZvRaEVZWo+QlIX8yqdSwqxLk1WtAIRzvlcj7NKum8xBxPed6BNFep/PtgIAmoLT5
500L8wb7EWb2iUdc2KbZ4OaY51lDScqpATgXu3WjXfM+Q52G0mX6Wyd0cjlL711Zrjb
501yLbiueZT94lgIHHRRKtKc8CEqcjkQV5OzABS3P/gQSfgZXBdLKjOpTnKDUq7IBeH
502AoIBBweAOEIAPLQg1QRUrr3xRrYKRwlakgZDii9wJt1l5AgBTICzbTA1vzDJ1JM5
503AqSpCV6w9JWyYVcXK+HLdKBRZLaPPNEQDJ5lOxD6uMziWGl2rg8tj+1xNMWfxiPz
504aTCjoe4EoBUMoTq2gwzRcM2usEQNikXVhnj9Wzaivsaeb4bJ3GRPW5DkrO6JSEtT
505w+gvyMqQM2Hy5k7E7BT46sXVwaj/jZxuqGnebRixXtnp0WixdRIqYWUr1UqLf6hQ
506G7WP2BgoxCMaCmNW8+HMD/xuxucEotoIhZ+GgJKBFoNnjl3BX+qxYdSe9RbL/5Tr
5074It6Jxtj8uETJXEbv9Cg6v1agWPS9YY8RLTBAoIBBwrU2AsAUts6h1LgGLKK3UWZ
508oLH5E+4o+7HqSGRcRodVeN9NBXIYdHHOLeEG6YNGJiJ3bFP5ZQEu9iDsyoFVKJ9O
509Mw/y6dKZuxOCZ+X8FopSROg3yWfdOpAm6cnQZp3WqLNX4n/Q6WvKojfyEiPphjwT
5100ymrUJELXLWJmjUyPoAk6HgC0Gs28ZnEXbyhx7CSbZNFyCU/PNUDZwto3GisIPD3
511le7YjqHugezmjMGlA0sDw5aCXjfbl74vowRFYMO6e3ItApfSRgNV86CDoX74WI/5
512AYU/QVM4wGt8XGT2KwDFJaxYGKsGDMWmXY04dS+WPuetCbouWUusyFwRb9SzFave
513vYeU7Ab/
514-----END RSA PRIVATE KEY-----""")
515
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400516
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400517class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400518 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900519 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400520 """
521
522 def setUp(self):
523 """
524 Create a new private key and start a certificate request (for a test
525 method to finish in one way or another).
526 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800527 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400528 # Basic setup stuff to generate a certificate
529 self.pkey = PKey()
530 self.pkey.generate_key(TYPE_RSA, 384)
531 self.req = X509Req()
532 self.req.set_pubkey(self.pkey)
533 # Authority good you have.
534 self.req.get_subject().commonName = "Yoda root CA"
535 self.x509 = X509()
536 self.subject = self.x509.get_subject()
537 self.subject.commonName = self.req.get_subject().commonName
538 self.x509.set_issuer(self.subject)
539 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400540 now = datetime.now()
541 expire = datetime.now() + timedelta(days=100)
542 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
543 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400544
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800545 def tearDown(self):
546 """
547 Forget all of the pyOpenSSL objects so they can be garbage collected,
548 their memory released, and not interfere with the leak detection code.
549 """
550 self.pkey = self.req = self.x509 = self.subject = None
551 super(X509ExtTests, self).tearDown()
552
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400553 def test_str(self):
554 """
Alex Gaynor31287502015-09-05 16:11:27 -0400555 The string representation of :py:class:`X509Extension` instances as
556 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400557 """
558 # This isn't necessarily the best string representation. Perhaps it
559 # will be changed/improved in the future.
560 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400561 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400562 'CA:FALSE')
563
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400564 def test_type(self):
565 """
Alex Gaynor31287502015-09-05 16:11:27 -0400566 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
567 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400568 """
569 self.assertIdentical(X509Extension, X509ExtensionType)
570 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400571 X509Extension,
572 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400573
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500574 def test_construction(self):
575 """
Alex Gaynor31287502015-09-05 16:11:27 -0400576 :py:class:`X509Extension` accepts an extension type name, a critical
577 flag, and an extension value and returns an
578 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500579 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400580 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500581 self.assertTrue(
582 isinstance(basic, X509ExtensionType),
583 "%r is of type %r, should be %r" % (
584 basic, type(basic), X509ExtensionType))
585
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400586 comment = X509Extension(
587 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500588 self.assertTrue(
589 isinstance(comment, X509ExtensionType),
590 "%r is of type %r, should be %r" % (
591 comment, type(comment), X509ExtensionType))
592
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500593 def test_invalid_extension(self):
594 """
Alex Gaynor31287502015-09-05 16:11:27 -0400595 :py:class:`X509Extension` raises something if it is passed a bad
596 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500597 """
598 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400599 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500600 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400601 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500602
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500603 # Exercise a weird one (an extension which uses the r2i method). This
604 # exercises the codepath that requires a non-NULL ctx to be passed to
605 # X509V3_EXT_nconf. It can't work now because we provide no
606 # configuration database. It might be made to work in the future.
607 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400608 Error, X509Extension, b('proxyCertInfo'), True,
609 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500610
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500611 def test_get_critical(self):
612 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900613 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500614 extension's critical flag.
615 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400616 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500617 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400618 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500619 self.assertFalse(ext.get_critical())
620
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500621 def test_get_short_name(self):
622 """
Alex Gaynor31287502015-09-05 16:11:27 -0400623 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
624 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500625 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400626 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
627 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
628 ext = X509Extension(b('nsComment'), True, b('foo bar'))
629 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500630
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400631 def test_get_data(self):
632 """
Alex Gaynor31287502015-09-05 16:11:27 -0400633 :py:meth:`X509Extension.get_data` returns a string giving the data of
634 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400635 """
636 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
637 # Expect to get back the DER encoded form of CA:true.
638 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
639
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400640 def test_get_data_wrong_args(self):
641 """
Alex Gaynor31287502015-09-05 16:11:27 -0400642 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
643 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400644 """
645 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
646 self.assertRaises(TypeError, ext.get_data, None)
647 self.assertRaises(TypeError, ext.get_data, "foo")
648 self.assertRaises(TypeError, ext.get_data, 7)
649
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400650 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500651 """
Alex Gaynor31287502015-09-05 16:11:27 -0400652 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
653 provided for an extension which does not use it and is ignored in this
654 case.
Rick Dean47262da2009-07-08 16:17:17 -0500655 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400656 ext1 = X509Extension(
657 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400658 self.x509.add_extensions([ext1])
659 self.x509.sign(self.pkey, 'sha1')
660 # This is a little lame. Can we think of a better way?
661 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400662 self.assertTrue(b('X509v3 Basic Constraints:') in text)
663 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400664
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400665 def test_subject(self):
666 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900667 If an extension requires a subject, the :py:data:`subject` parameter to
668 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400669 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400670 ext3 = X509Extension(
671 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400672 self.x509.add_extensions([ext3])
673 self.x509.sign(self.pkey, 'sha1')
674 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400675 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400676
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400677 def test_missing_subject(self):
678 """
Alex Gaynor31287502015-09-05 16:11:27 -0400679 If an extension requires a subject and the :py:data:`subject` parameter
680 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400681 """
682 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400683 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400684
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400685 def test_invalid_subject(self):
686 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900687 If the :py:data:`subject` parameter is given a value which is not an
688 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400689 """
690 for badObj in [True, object(), "hello", [], self]:
691 self.assertRaises(
692 TypeError,
693 X509Extension,
694 'basicConstraints', False, 'CA:TRUE', subject=badObj)
695
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400696 def test_unused_issuer(self):
697 """
Alex Gaynor31287502015-09-05 16:11:27 -0400698 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
699 provided for an extension which does not use it and is ignored in this
700 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400701 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400702 ext1 = X509Extension(
703 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400704 self.x509.add_extensions([ext1])
705 self.x509.sign(self.pkey, 'sha1')
706 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400707 self.assertTrue(b('X509v3 Basic Constraints:') in text)
708 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400709
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400710 def test_issuer(self):
711 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800712 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900713 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400714 """
715 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400716 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400717 issuer=self.x509)
718 self.x509.add_extensions([ext2])
719 self.x509.sign(self.pkey, 'sha1')
720 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400721 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
722 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400723
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400724 def test_missing_issuer(self):
725 """
Alex Gaynor31287502015-09-05 16:11:27 -0400726 If an extension requires an issue and the :py:data:`issuer` parameter
727 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400728 """
729 self.assertRaises(
730 Error,
731 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400732 b('authorityKeyIdentifier'), False,
733 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400734
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400735 def test_invalid_issuer(self):
736 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900737 If the :py:data:`issuer` parameter is given a value which is not an
738 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400739 """
740 for badObj in [True, object(), "hello", [], self]:
741 self.assertRaises(
742 TypeError,
743 X509Extension,
744 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
745 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500746
747
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400748class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500749 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900750 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500751 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400752
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400753 def test_type(self):
754 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900755 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
756 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400757 """
758 self.assertIdentical(PKey, PKeyType)
759 self.assertConsistentType(PKey, 'PKey')
760
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500761 def test_construction(self):
762 """
Alex Gaynor31287502015-09-05 16:11:27 -0400763 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
764 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500765 """
766 self.assertRaises(TypeError, PKey, None)
767 key = PKey()
768 self.assertTrue(
769 isinstance(key, PKeyType),
770 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
771
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500772 def test_pregeneration(self):
773 """
Alex Gaynor31287502015-09-05 16:11:27 -0400774 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
775 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
776 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500777 """
778 key = PKey()
779 self.assertEqual(key.type(), 0)
780 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400781 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500782
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500783 def test_failedGeneration(self):
784 """
Alex Gaynor31287502015-09-05 16:11:27 -0400785 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
786 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
787 the second giving the number of bits to generate. If an invalid type
788 is specified or generation fails, :py:exc:`Error` is raised. If an
789 invalid number of bits is specified, :py:exc:`ValueError` or
790 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500791 """
792 key = PKey()
793 self.assertRaises(TypeError, key.generate_key)
794 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
795 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
796 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500797
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500798 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
799 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500800
801 # XXX RSA generation for small values of bits is fairly buggy in a wide
802 # range of OpenSSL versions. I need to figure out what the safe lower
803 # bound for a reasonable number of OpenSSL versions is and explicitly
804 # check for that in the wrapper. The failure behavior is typically an
805 # infinite loop inside OpenSSL.
806
807 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500808
809 # XXX DSA generation seems happy with any number of bits. The DSS
810 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
811 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500812 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500813 # So, it doesn't seem possible to make generate_key fail for
814 # TYPE_DSA with a bits argument which is at least an int.
815
816 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
817
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500818 def test_rsaGeneration(self):
819 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900820 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
821 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500822 """
823 bits = 128
824 key = PKey()
825 key.generate_key(TYPE_RSA, bits)
826 self.assertEqual(key.type(), TYPE_RSA)
827 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400828 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500829
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500830 def test_dsaGeneration(self):
831 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900832 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
833 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500834 """
835 # 512 is a magic number. The DSS (Digital Signature Standard)
836 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
837 # will silently promote any value below 512 to 512.
838 bits = 512
839 key = PKey()
840 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800841 # self.assertEqual(key.type(), TYPE_DSA)
842 # self.assertEqual(key.bits(), bits)
843 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500844
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500845 def test_regeneration(self):
846 """
Alex Gaynor31287502015-09-05 16:11:27 -0400847 :py:meth:`PKeyType.generate_key` can be called multiple times on the
848 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500849 """
850 key = PKey()
851 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400852 key.generate_key(type, bits)
853 self.assertEqual(key.type(), type)
854 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500855
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400856 def test_inconsistentKey(self):
857 """
Alex Gaynor31287502015-09-05 16:11:27 -0400858 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
859 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400860 """
861 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400862 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400863
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400864 def test_check_wrong_args(self):
865 """
Alex Gaynor31287502015-09-05 16:11:27 -0400866 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
867 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400868 """
869 self.assertRaises(TypeError, PKey().check, None)
870 self.assertRaises(TypeError, PKey().check, object())
871 self.assertRaises(TypeError, PKey().check, 1)
872
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400873 def test_check_public_key(self):
874 """
875 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
876 part of the key is available.
877 """
878 # A trick to get a public-only key
879 key = PKey()
880 key.generate_key(TYPE_RSA, 512)
881 cert = X509()
882 cert.set_pubkey(key)
883 pub = cert.get_pubkey()
884 self.assertRaises(TypeError, pub.check)
885
886
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400887class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500888 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900889 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500890 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400891
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500892 def _x509name(self, **attrs):
893 # XXX There's no other way to get a new X509Name yet.
894 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400895 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400896
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500897 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400898 def key(attr):
899 return attr[1]
900 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500901 for k, v in attrs:
902 setattr(name, k, v)
903 return name
904
Rick Deane15b1472009-07-09 15:53:42 -0500905 def test_type(self):
906 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900907 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500908 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400909 self.assertIdentical(X509Name, X509NameType)
910 self.assertEqual(X509NameType.__name__, 'X509Name')
911 self.assertTrue(isinstance(X509NameType, type))
912
Rick Deane15b1472009-07-09 15:53:42 -0500913 name = self._x509name()
914 self.assertTrue(
915 isinstance(name, X509NameType),
916 "%r is of type %r, should be %r" % (
917 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500918
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400919 def test_onlyStringAttributes(self):
920 """
Alex Gaynor31287502015-09-05 16:11:27 -0400921 Attempting to set a non-:py:data:`str` attribute name on an
922 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
923 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400924 """
925 name = self._x509name()
926 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400927 # rejected. Sorry, you're wrong. unicode is automatically converted
928 # to str outside of the control of X509Name, so there's no way to
929 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800930
Alex Gaynor31287502015-09-05 16:11:27 -0400931 # Also, this used to test str subclasses, but that test is less
932 # relevant now that the implementation is in Python instead of C. Also
933 # PyPy automatically converts str subclasses to str when they are
934 # passed to setattr, so we can't test it on PyPy. Apparently CPython
935 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400936 self.assertRaises(TypeError, setattr, name, None, "hello")
937 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400938
939 def test_setInvalidAttribute(self):
940 """
Alex Gaynor31287502015-09-05 16:11:27 -0400941 Attempting to set any attribute name on an :py:class:`X509NameType`
942 instance for which no corresponding NID is defined causes
943 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400944 """
945 name = self._x509name()
946 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
947
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500948 def test_attributes(self):
949 """
Alex Gaynor31287502015-09-05 16:11:27 -0400950 :py:class:`X509NameType` instances have attributes for each standard
951 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500952 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500953 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500954 name.commonName = "foo"
955 self.assertEqual(name.commonName, "foo")
956 self.assertEqual(name.CN, "foo")
957 name.CN = "baz"
958 self.assertEqual(name.commonName, "baz")
959 self.assertEqual(name.CN, "baz")
960 name.commonName = "bar"
961 self.assertEqual(name.commonName, "bar")
962 self.assertEqual(name.CN, "bar")
963 name.CN = "quux"
964 self.assertEqual(name.commonName, "quux")
965 self.assertEqual(name.CN, "quux")
966
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500967 def test_copy(self):
968 """
Alex Gaynor31287502015-09-05 16:11:27 -0400969 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
970 with all the same attributes as an existing :py:class:`X509NameType`
971 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500972 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500973 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500974
975 copy = X509Name(name)
976 self.assertEqual(copy.commonName, "foo")
977 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500978
979 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500980 copy.commonName = "baz"
981 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500982
983 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500984 name.emailAddress = "quux@example.com"
985 self.assertEqual(copy.emailAddress, "bar@example.com")
986
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500987 def test_repr(self):
988 """
Alex Gaynor31287502015-09-05 16:11:27 -0400989 :py:func:`repr` passed an :py:class:`X509NameType` instance should
990 return a string containing a description of the type and the NIDs which
991 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500992 """
993 name = self._x509name(commonName="foo", emailAddress="bar")
994 self.assertEqual(
995 repr(name),
996 "<X509Name object '/emailAddress=bar/CN=foo'>")
997
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500998 def test_comparison(self):
999 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001000 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001001 """
1002 def _equality(a, b, assertTrue, assertFalse):
1003 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
1004 assertFalse(a != b)
1005 assertTrue(b == a)
1006 assertFalse(b != a)
1007
1008 def assertEqual(a, b):
1009 _equality(a, b, self.assertTrue, self.assertFalse)
1010
1011 # Instances compare equal to themselves.
1012 name = self._x509name()
1013 assertEqual(name, name)
1014
1015 # Empty instances should compare equal to each other.
1016 assertEqual(self._x509name(), self._x509name())
1017
1018 # Instances with equal NIDs should compare equal to each other.
1019 assertEqual(self._x509name(commonName="foo"),
1020 self._x509name(commonName="foo"))
1021
1022 # Instance with equal NIDs set using different aliases should compare
1023 # equal to each other.
1024 assertEqual(self._x509name(commonName="foo"),
1025 self._x509name(CN="foo"))
1026
1027 # Instances with more than one NID with the same values should compare
1028 # equal to each other.
1029 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
1030 self._x509name(commonName="foo", OU="bar"))
1031
1032 def assertNotEqual(a, b):
1033 _equality(a, b, self.assertFalse, self.assertTrue)
1034
1035 # Instances with different values for the same NID should not compare
1036 # equal to each other.
1037 assertNotEqual(self._x509name(CN="foo"),
1038 self._x509name(CN="bar"))
1039
1040 # Instances with different NIDs should not compare equal to each other.
1041 assertNotEqual(self._x509name(CN="foo"),
1042 self._x509name(OU="foo"))
1043
1044 def _inequality(a, b, assertTrue, assertFalse):
1045 assertTrue(a < b)
1046 assertTrue(a <= b)
1047 assertTrue(b > a)
1048 assertTrue(b >= a)
1049 assertFalse(a > b)
1050 assertFalse(a >= b)
1051 assertFalse(b < a)
1052 assertFalse(b <= a)
1053
1054 def assertLessThan(a, b):
1055 _inequality(a, b, self.assertTrue, self.assertFalse)
1056
1057 # An X509Name with a NID with a value which sorts less than the value
1058 # of the same NID on another X509Name compares less than the other
1059 # X509Name.
1060 assertLessThan(self._x509name(CN="abc"),
1061 self._x509name(CN="def"))
1062
1063 def assertGreaterThan(a, b):
1064 _inequality(a, b, self.assertFalse, self.assertTrue)
1065
1066 # An X509Name with a NID with a value which sorts greater than the
1067 # value of the same NID on another X509Name compares greater than the
1068 # other X509Name.
1069 assertGreaterThan(self._x509name(CN="def"),
1070 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001071
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001072 def test_hash(self):
1073 """
Alex Gaynor31287502015-09-05 16:11:27 -04001074 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1075 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001076 """
1077 a = self._x509name(CN="foo")
1078 b = self._x509name(CN="foo")
1079 self.assertEqual(a.hash(), b.hash())
1080 a.CN = "bar"
1081 self.assertNotEqual(a.hash(), b.hash())
1082
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001083 def test_der(self):
1084 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001085 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001086 """
1087 a = self._x509name(CN="foo", C="US")
1088 self.assertEqual(
1089 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001090 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001091 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001092
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001093 def test_get_components(self):
1094 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001095 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1096 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001097 giving the NIDs and associated values which make up the name.
1098 """
1099 a = self._x509name()
1100 self.assertEqual(a.get_components(), [])
1101 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001102 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001103 a.organizationalUnitName = "bar"
1104 self.assertEqual(
1105 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001106 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001107
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001108 def test_load_nul_byte_attribute(self):
1109 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001110 An :py:class:`OpenSSL.crypto.X509Name` from an
1111 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001112 NUL byte in the value of one of its attributes.
1113 """
1114 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1115 subject = cert.get_subject()
1116 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001117 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001118
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001119 def test_setAttributeFailure(self):
1120 """
1121 If the value of an attribute cannot be set for some reason then
1122 :py:class:`OpenSSL.crypto.Error` is raised.
1123 """
1124 name = self._x509name()
1125 # This value is too long
1126 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1127
1128
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001129class _PKeyInteractionTestsMixin:
1130 """
1131 Tests which involve another thing and a PKey.
1132 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001133
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001134 def signable(self):
1135 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001136 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1137 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001138 """
1139 raise NotImplementedError()
1140
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001141 def test_signWithUngenerated(self):
1142 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001143 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1144 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001145 """
1146 request = self.signable()
1147 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001148 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001149
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001150 def test_signWithPublicKey(self):
1151 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001152 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1153 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001154 """
1155 request = self.signable()
1156 key = PKey()
1157 key.generate_key(TYPE_RSA, 512)
1158 request.set_pubkey(key)
1159 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001160 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001161
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001162 def test_signWithUnknownDigest(self):
1163 """
Alex Gaynor31287502015-09-05 16:11:27 -04001164 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1165 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001166 """
1167 request = self.signable()
1168 key = PKey()
1169 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001170 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001171
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001172 def test_sign(self):
1173 """
Alex Gaynor31287502015-09-05 16:11:27 -04001174 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1175 valid digest function. :py:meth:`X509Req.verify` can be used to check
1176 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001177 """
1178 request = self.signable()
1179 key = PKey()
1180 key.generate_key(TYPE_RSA, 512)
1181 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001182 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001183 # If the type has a verify method, cover that too.
1184 if getattr(request, 'verify', None) is not None:
1185 pub = request.get_pubkey()
1186 self.assertTrue(request.verify(pub))
1187 # Make another key that won't verify.
1188 key = PKey()
1189 key.generate_key(TYPE_RSA, 512)
1190 self.assertRaises(Error, request.verify, key)
1191
1192
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001193class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001194 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001195 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001196 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001197
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001198 def signable(self):
1199 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001200 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001201 """
1202 return X509Req()
1203
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001204 def test_type(self):
1205 """
Alex Gaynor31287502015-09-05 16:11:27 -04001206 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1207 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001208 """
1209 self.assertIdentical(X509Req, X509ReqType)
1210 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001211
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001212 def test_construction(self):
1213 """
Alex Gaynor31287502015-09-05 16:11:27 -04001214 :py:obj:`X509Req` takes no arguments and returns an
1215 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001216 """
1217 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001218 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001219
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001220 def test_version(self):
1221 """
Alex Gaynor31287502015-09-05 16:11:27 -04001222 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1223 certificate request. :py:obj:`X509ReqType.get_version` returns the
1224 X.509 version of the certificate request. The initial value of the
1225 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001226 """
1227 request = X509Req()
1228 self.assertEqual(request.get_version(), 0)
1229 request.set_version(1)
1230 self.assertEqual(request.get_version(), 1)
1231 request.set_version(3)
1232 self.assertEqual(request.get_version(), 3)
1233
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001234 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001235 """
Alex Gaynor31287502015-09-05 16:11:27 -04001236 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1237 with the wrong number of arguments or with a non-:py:obj:`int`
1238 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1239 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001240 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001241 request = X509Req()
1242 self.assertRaises(TypeError, request.set_version)
1243 self.assertRaises(TypeError, request.set_version, "foo")
1244 self.assertRaises(TypeError, request.set_version, 1, 2)
1245 self.assertRaises(TypeError, request.get_version, None)
1246
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001247 def test_get_subject(self):
1248 """
Alex Gaynor31287502015-09-05 16:11:27 -04001249 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1250 subject of the request and which is valid even after the request object
1251 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001252 """
1253 request = X509Req()
1254 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001255 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001256 subject.commonName = "foo"
1257 self.assertEqual(request.get_subject().commonName, "foo")
1258 del request
1259 subject.commonName = "bar"
1260 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001261
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001262 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001263 """
Alex Gaynor31287502015-09-05 16:11:27 -04001264 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1265 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001266 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001267 request = X509Req()
1268 self.assertRaises(TypeError, request.get_subject, None)
1269
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001270 def test_add_extensions(self):
1271 """
Alex Gaynor31287502015-09-05 16:11:27 -04001272 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1273 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001274 """
1275 request = X509Req()
1276 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001277 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001278 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001279 self.assertEqual(len(exts), 1)
1280 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1281 self.assertEqual(exts[0].get_critical(), 1)
1282 self.assertEqual(exts[0].get_data(), b('0\x00'))
1283
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001284 def test_get_extensions(self):
1285 """
1286 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1287 extensions added to this X509 request.
1288 """
1289 request = X509Req()
1290 exts = request.get_extensions()
1291 self.assertEqual(exts, [])
1292 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001293 X509Extension(b('basicConstraints'), True, b('CA:true')),
1294 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001295 exts = request.get_extensions()
1296 self.assertEqual(len(exts), 2)
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\x03\x01\x01\xff'))
1300 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1301 self.assertEqual(exts[1].get_critical(), 0)
1302 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001303
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001304 def test_add_extensions_wrong_args(self):
1305 """
Alex Gaynor31287502015-09-05 16:11:27 -04001306 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1307 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1308 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1309 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001310 """
1311 request = X509Req()
1312 self.assertRaises(TypeError, request.add_extensions)
1313 self.assertRaises(TypeError, request.add_extensions, object())
1314 self.assertRaises(ValueError, request.add_extensions, [object()])
1315 self.assertRaises(TypeError, request.add_extensions, [], None)
1316
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001317 def test_verify_wrong_args(self):
1318 """
1319 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1320 arguments or more than one argument or if passed anything other than a
1321 :py:obj:`PKey` instance as its single argument.
1322 """
1323 request = X509Req()
1324 self.assertRaises(TypeError, request.verify)
1325 self.assertRaises(TypeError, request.verify, object())
1326 self.assertRaises(TypeError, request.verify, PKey(), object())
1327
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001328 def test_verify_uninitialized_key(self):
1329 """
Alex Gaynor31287502015-09-05 16:11:27 -04001330 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1331 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001332 """
1333 request = X509Req()
1334 pkey = PKey()
1335 self.assertRaises(Error, request.verify, pkey)
1336
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001337 def test_verify_wrong_key(self):
1338 """
Alex Gaynor31287502015-09-05 16:11:27 -04001339 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1340 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1341 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001342 """
1343 request = X509Req()
1344 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001345 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001346 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1347 self.assertRaises(Error, request.verify, another_pkey)
1348
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001349 def test_verify_success(self):
1350 """
1351 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001352 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1353 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001354 """
1355 request = X509Req()
1356 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001357 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001358 self.assertEqual(True, request.verify(pkey))
1359
1360
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001361class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001362 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001363 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001364 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001365 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001366
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001367 extpem = """
1368-----BEGIN CERTIFICATE-----
1369MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1370BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1371eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1372MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1373aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1374hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1375Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1376zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1377hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1378TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
137903HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1380MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1381b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1382MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1383uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1384WpOdIpB8KksUTCzV591Nr1wd
1385-----END CERTIFICATE-----
1386 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001387
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001388 def signable(self):
1389 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001390 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001391 """
1392 return X509()
1393
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001394 def test_type(self):
1395 """
Alex Gaynor31287502015-09-05 16:11:27 -04001396 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1397 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001398 """
1399 self.assertIdentical(X509, X509Type)
1400 self.assertConsistentType(X509, 'X509')
1401
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001402 def test_construction(self):
1403 """
Alex Gaynor31287502015-09-05 16:11:27 -04001404 :py:obj:`X509` takes no arguments and returns an instance of
1405 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001406 """
1407 certificate = X509()
1408 self.assertTrue(
1409 isinstance(certificate, X509Type),
1410 "%r is of type %r, should be %r" % (certificate,
1411 type(certificate),
1412 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001413 self.assertEqual(type(X509Type).__name__, 'type')
1414 self.assertEqual(type(certificate).__name__, 'X509')
1415 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001416 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001417
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001418 def test_get_version_wrong_args(self):
1419 """
Alex Gaynor31287502015-09-05 16:11:27 -04001420 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1421 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001422 """
1423 cert = X509()
1424 self.assertRaises(TypeError, cert.get_version, None)
1425
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001426 def test_set_version_wrong_args(self):
1427 """
Alex Gaynor31287502015-09-05 16:11:27 -04001428 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1429 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001430 """
1431 cert = X509()
1432 self.assertRaises(TypeError, cert.set_version)
1433 self.assertRaises(TypeError, cert.set_version, None)
1434 self.assertRaises(TypeError, cert.set_version, 1, None)
1435
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001436 def test_version(self):
1437 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001438 :py:obj:`X509.set_version` sets the certificate version number.
1439 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001440 """
1441 cert = X509()
1442 cert.set_version(1234)
1443 self.assertEquals(cert.get_version(), 1234)
1444
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001445 def test_get_serial_number_wrong_args(self):
1446 """
Alex Gaynor31287502015-09-05 16:11:27 -04001447 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1448 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001449 """
1450 cert = X509()
1451 self.assertRaises(TypeError, cert.get_serial_number, None)
1452
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001453 def test_serial_number(self):
1454 """
Alex Gaynor31287502015-09-05 16:11:27 -04001455 The serial number of an :py:obj:`X509Type` can be retrieved and
1456 modified with :py:obj:`X509Type.get_serial_number` and
1457 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001458 """
1459 certificate = X509()
1460 self.assertRaises(TypeError, certificate.set_serial_number)
1461 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1462 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1463 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1464 self.assertEqual(certificate.get_serial_number(), 0)
1465 certificate.set_serial_number(1)
1466 self.assertEqual(certificate.get_serial_number(), 1)
1467 certificate.set_serial_number(2 ** 32 + 1)
1468 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1469 certificate.set_serial_number(2 ** 64 + 1)
1470 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001471 certificate.set_serial_number(2 ** 128 + 1)
1472 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1473
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001474 def _setBoundTest(self, which):
1475 """
Alex Gaynor31287502015-09-05 16:11:27 -04001476 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1477 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1478 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001479 """
1480 certificate = X509()
1481 set = getattr(certificate, 'set_not' + which)
1482 get = getattr(certificate, 'get_not' + which)
1483
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001484 # Starts with no value.
1485 self.assertEqual(get(), None)
1486
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001487 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001488 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001489 set(when)
1490 self.assertEqual(get(), when)
1491
1492 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001493 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001494 set(when)
1495 self.assertEqual(get(), when)
1496
1497 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001498 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001499 set(when)
1500 self.assertEqual(get(), when)
1501
1502 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001503 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001504
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001505 # The wrong number of arguments results in a TypeError.
1506 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001507 with pytest.raises(TypeError):
1508 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001509 self.assertRaises(TypeError, get, b("foo bar"))
1510
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001511 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001512
1513 def test_set_notBefore(self):
1514 """
Alex Gaynor31287502015-09-05 16:11:27 -04001515 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1516 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1517 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001518 """
1519 self._setBoundTest("Before")
1520
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001521 def test_set_notAfter(self):
1522 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001523 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001524 GENERALIZEDTIME and sets the end of the certificate's validity period
1525 to it.
1526 """
1527 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001528
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001529 def test_get_notBefore(self):
1530 """
Alex Gaynor31287502015-09-05 16:11:27 -04001531 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1532 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001533 internally.
1534 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001535 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001536 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001537
Rick Dean38a05c82009-07-18 01:41:30 -05001538 def test_get_notAfter(self):
1539 """
Alex Gaynor31287502015-09-05 16:11:27 -04001540 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1541 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001542 internally.
1543 """
1544 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001545 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001546
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001547 def test_gmtime_adj_notBefore_wrong_args(self):
1548 """
Alex Gaynor31287502015-09-05 16:11:27 -04001549 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1550 called with the wrong number of arguments or a non-:py:obj:`int`
1551 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001552 """
1553 cert = X509()
1554 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1555 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1556 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1557
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001558 def test_gmtime_adj_notBefore(self):
1559 """
Alex Gaynor31287502015-09-05 16:11:27 -04001560 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1561 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001562 """
1563 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001564 not_before_min = (
1565 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1566 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001567 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001568 not_before = datetime.strptime(
1569 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1570 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001571 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1572 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001573
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001574 def test_gmtime_adj_notAfter_wrong_args(self):
1575 """
Alex Gaynor31287502015-09-05 16:11:27 -04001576 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1577 called with the wrong number of arguments or a non-:py:obj:`int`
1578 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001579 """
1580 cert = X509()
1581 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1582 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1583 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1584
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001585 def test_gmtime_adj_notAfter(self):
1586 """
Alex Gaynor31287502015-09-05 16:11:27 -04001587 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1588 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001589 """
1590 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001591 not_after_min = (
1592 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1593 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001594 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001595 not_after = datetime.strptime(
1596 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1597 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001598 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1599 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001600
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001601 def test_has_expired_wrong_args(self):
1602 """
Alex Gaynor31287502015-09-05 16:11:27 -04001603 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1604 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001605 """
1606 cert = X509()
1607 self.assertRaises(TypeError, cert.has_expired, None)
1608
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001609 def test_has_expired(self):
1610 """
Alex Gaynor31287502015-09-05 16:11:27 -04001611 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1612 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001613 """
1614 cert = X509()
1615 cert.gmtime_adj_notAfter(-1)
1616 self.assertTrue(cert.has_expired())
1617
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001618 def test_has_not_expired(self):
1619 """
Alex Gaynor31287502015-09-05 16:11:27 -04001620 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1621 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001622 """
1623 cert = X509()
1624 cert.gmtime_adj_notAfter(2)
1625 self.assertFalse(cert.has_expired())
1626
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001627 def test_root_has_not_expired(self):
1628 """
Alex Gaynor31287502015-09-05 16:11:27 -04001629 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1630 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001631 """
1632 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1633 self.assertFalse(cert.has_expired())
1634
Rick Dean38a05c82009-07-18 01:41:30 -05001635 def test_digest(self):
1636 """
Alex Gaynor31287502015-09-05 16:11:27 -04001637 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1638 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001639 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001640 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001641 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001642 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1643 # actually matters to the assertion (ie, another arbitrary, good
1644 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001645 # Digest verified with the command:
1646 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001647 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001648 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001649
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001650 def _extcert(self, pkey, extensions):
1651 cert = X509()
1652 cert.set_pubkey(pkey)
1653 cert.get_subject().commonName = "Unit Tests"
1654 cert.get_issuer().commonName = "Unit Tests"
1655 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1656 cert.set_notBefore(when)
1657 cert.set_notAfter(when)
1658
1659 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001660 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001661 return load_certificate(
1662 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1663
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001664 def test_extension_count(self):
1665 """
Alex Gaynor31287502015-09-05 16:11:27 -04001666 :py:obj:`X509.get_extension_count` returns the number of extensions
1667 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001668 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001669 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001670 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1671 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001672 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001673 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001674
1675 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001676 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001677 self.assertEqual(c.get_extension_count(), 0)
1678
1679 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001680 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001681 self.assertEqual(c.get_extension_count(), 1)
1682
1683 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001684 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001685 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001686
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001687 def test_get_extension(self):
1688 """
Alex Gaynor31287502015-09-05 16:11:27 -04001689 :py:obj:`X509.get_extension` takes an integer and returns an
1690 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001691 """
1692 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001693 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1694 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001695 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001696 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001697
1698 cert = self._extcert(pkey, [ca, key, subjectAltName])
1699
1700 ext = cert.get_extension(0)
1701 self.assertTrue(isinstance(ext, X509Extension))
1702 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001703 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001704
1705 ext = cert.get_extension(1)
1706 self.assertTrue(isinstance(ext, X509Extension))
1707 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001708 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001709
1710 ext = cert.get_extension(2)
1711 self.assertTrue(isinstance(ext, X509Extension))
1712 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001713 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001714
1715 self.assertRaises(IndexError, cert.get_extension, -1)
1716 self.assertRaises(IndexError, cert.get_extension, 4)
1717 self.assertRaises(TypeError, cert.get_extension, "hello")
1718
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001719 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001720 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001721 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001722 bytes and this value is reflected in the string representation of the
1723 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001724 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001725 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001726
1727 ext = cert.get_extension(3)
1728 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001729 self.assertEqual(
1730 b("DNS:altnull.python.org\x00example.com, "
1731 "email:null@python.org\x00user@example.org, "
1732 "URI:http://null.python.org\x00http://example.org, "
1733 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1734 b(str(ext)))
1735
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001736 def test_invalid_digest_algorithm(self):
1737 """
Alex Gaynor31287502015-09-05 16:11:27 -04001738 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1739 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001740 """
1741 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001742 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001743
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001744 def test_get_subject_wrong_args(self):
1745 """
Alex Gaynor31287502015-09-05 16:11:27 -04001746 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1747 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001748 """
1749 cert = X509()
1750 self.assertRaises(TypeError, cert.get_subject, None)
1751
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001752 def test_get_subject(self):
1753 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001754 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001755 """
1756 cert = load_certificate(FILETYPE_PEM, self.pemData)
1757 subj = cert.get_subject()
1758 self.assertTrue(isinstance(subj, X509Name))
1759 self.assertEquals(
1760 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001761 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1762 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001763
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001764 def test_set_subject_wrong_args(self):
1765 """
Alex Gaynor31287502015-09-05 16:11:27 -04001766 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1767 the wrong number of arguments or an argument not of type
1768 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001769 """
1770 cert = X509()
1771 self.assertRaises(TypeError, cert.set_subject)
1772 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001773 with pytest.raises(TypeError):
1774 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001775
1776 def test_set_subject(self):
1777 """
Alex Gaynor31287502015-09-05 16:11:27 -04001778 :py:obj:`X509.set_subject` changes the subject of the certificate to
1779 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001780 """
1781 cert = X509()
1782 name = cert.get_subject()
1783 name.C = 'AU'
1784 name.O = 'Unit Tests'
1785 cert.set_subject(name)
1786 self.assertEquals(
1787 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001788 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001789
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001790 def test_get_issuer_wrong_args(self):
1791 """
Alex Gaynor31287502015-09-05 16:11:27 -04001792 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1793 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001794 """
1795 cert = X509()
1796 self.assertRaises(TypeError, cert.get_issuer, None)
1797
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001798 def test_get_issuer(self):
1799 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001800 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001801 """
1802 cert = load_certificate(FILETYPE_PEM, self.pemData)
1803 subj = cert.get_issuer()
1804 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001805 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001806 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001807 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001808 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1809 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001810
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001811 def test_set_issuer_wrong_args(self):
1812 """
Alex Gaynor31287502015-09-05 16:11:27 -04001813 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1814 the wrong number of arguments or an argument not of type
1815 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001816 """
1817 cert = X509()
1818 self.assertRaises(TypeError, cert.set_issuer)
1819 self.assertRaises(TypeError, cert.set_issuer, None)
1820 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1821
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001822 def test_set_issuer(self):
1823 """
Alex Gaynor31287502015-09-05 16:11:27 -04001824 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1825 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001826 """
1827 cert = X509()
1828 name = cert.get_issuer()
1829 name.C = 'AU'
1830 name.O = 'Unit Tests'
1831 cert.set_issuer(name)
1832 self.assertEquals(
1833 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001834 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001835
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001836 def test_get_pubkey_uninitialized(self):
1837 """
Alex Gaynor31287502015-09-05 16:11:27 -04001838 When called on a certificate with no public key,
1839 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001840 """
1841 cert = X509()
1842 self.assertRaises(Error, cert.get_pubkey)
1843
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001844 def test_subject_name_hash_wrong_args(self):
1845 """
Alex Gaynor31287502015-09-05 16:11:27 -04001846 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1847 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001848 """
1849 cert = X509()
1850 self.assertRaises(TypeError, cert.subject_name_hash, None)
1851
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001852 def test_subject_name_hash(self):
1853 """
Alex Gaynor31287502015-09-05 16:11:27 -04001854 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1855 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001856 """
1857 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001858 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001859 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001860 [3350047874, # OpenSSL 0.9.8, MD5
1861 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001862 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001863
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001864 def test_get_signature_algorithm(self):
1865 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001866 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001867 the algorithm used to sign the certificate.
1868 """
1869 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001870 self.assertEqual(
1871 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001872
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001873 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001874 """
Alex Gaynor31287502015-09-05 16:11:27 -04001875 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1876 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001877 """
1878 # This certificate has been modified to indicate a bogus OID in the
1879 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001880 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001881-----BEGIN CERTIFICATE-----
1882MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1883EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1884cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1885MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1886EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1887CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1888AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1889+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1890hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1891BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1892FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1893dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1894aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1895MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1896jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1897PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1898tgI5
1899-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001900""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001901 cert = load_certificate(FILETYPE_PEM, certPEM)
1902 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001903
1904
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001905class X509StoreTests(TestCase):
1906 """
1907 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1908 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001909
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001910 def test_type(self):
1911 """
1912 :py:obj:`X509StoreType` is a type object.
1913 """
1914 self.assertIdentical(X509Store, X509StoreType)
1915 self.assertConsistentType(X509Store, 'X509Store')
1916
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001917 def test_add_cert_wrong_args(self):
1918 store = X509Store()
1919 self.assertRaises(TypeError, store.add_cert)
1920 self.assertRaises(TypeError, store.add_cert, object())
1921 self.assertRaises(TypeError, store.add_cert, X509(), object())
1922
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001923 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001924 """
1925 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1926 certificate store.
1927 """
1928 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001929 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001930 store.add_cert(cert)
1931
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001932 def test_add_cert_rejects_duplicate(self):
1933 """
Alex Gaynor31287502015-09-05 16:11:27 -04001934 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1935 an attempt is made to add the same certificate to the store more than
1936 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001937 """
1938 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1939 store = X509Store()
1940 store.add_cert(cert)
1941 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001942
1943
Rick Dean623ee362009-07-17 12:22:16 -05001944class PKCS12Tests(TestCase):
1945 """
Alex Gaynor31287502015-09-05 16:11:27 -04001946 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1947 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001948 """
1949 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1950
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001951 def test_type(self):
1952 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001953 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001954 """
1955 self.assertIdentical(PKCS12, PKCS12Type)
1956 self.assertConsistentType(PKCS12, 'PKCS12')
1957
Rick Deanf94096c2009-07-18 14:23:06 -05001958 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001959 """
Alex Gaynor31287502015-09-05 16:11:27 -04001960 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1961 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001962 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001963 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001964 self.assertEqual(None, p12.get_certificate())
1965 self.assertEqual(None, p12.get_privatekey())
1966 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001967 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001968
1969 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001970 """
Alex Gaynor31287502015-09-05 16:11:27 -04001971 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1972 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1973 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1974 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001975 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001976 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001977 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001978 self.assertRaises(TypeError, p12.set_certificate, PKey())
1979 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001980 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001981 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1982 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001983 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1984 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1985 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001986 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001987 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1988 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001989
1990 def test_key_only(self):
1991 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001992 A :py:obj:`PKCS12` with only a private key can be exported using
1993 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001994 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001995 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001996 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001997 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001998 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05001999 self.assertEqual(None, p12.get_certificate())
2000 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002001 try:
2002 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2003 except Error:
2004 # Some versions of OpenSSL will throw an exception
2005 # for this nearly useless PKCS12 we tried to generate:
2006 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2007 return
Rick Dean623ee362009-07-17 12:22:16 -05002008 p12 = load_pkcs12(dumped_p12, passwd)
2009 self.assertEqual(None, p12.get_ca_certificates())
2010 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002011
2012 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2013 # future this will be improved.
2014 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05002015
2016 def test_cert_only(self):
2017 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002018 A :py:obj:`PKCS12` with only a certificate can be exported using
2019 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002020 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002021 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002022 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002023 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002024 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05002025 self.assertEqual(cert, p12.get_certificate())
2026 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002027 try:
2028 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2029 except Error:
2030 # Some versions of OpenSSL will throw an exception
2031 # for this nearly useless PKCS12 we tried to generate:
2032 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2033 return
Rick Dean623ee362009-07-17 12:22:16 -05002034 p12 = load_pkcs12(dumped_p12, passwd)
2035 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002036
2037 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
2038 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2039
2040 # Oh ho. It puts the certificate into the ca certificates list, in
2041 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2042 # that to check to see if it reconstructed the certificate we expected
2043 # it to. At some point, hopefully this will change so that
2044 # p12.get_certificate() is actually what returns the loaded
2045 # certificate.
2046 self.assertEqual(
2047 cleartextCertificatePEM,
2048 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002049
Alex Gaynor31287502015-09-05 16:11:27 -04002050 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2051 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002052 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002053 Generate a PKCS12 object with components from PEM. Verify that the set
2054 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002055 """
Rick Deanf94096c2009-07-18 14:23:06 -05002056 p12 = PKCS12()
2057 if cert_pem:
2058 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2059 self.assertEqual(ret, None)
2060 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002061 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002062 self.assertEqual(ret, None)
2063 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002064 ret = p12.set_ca_certificates(
2065 (load_certificate(FILETYPE_PEM, ca_pem),)
2066 )
Rick Deanf94096c2009-07-18 14:23:06 -05002067 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002068 if friendly_name:
2069 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002070 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002071 return p12
2072
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002073 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002074 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002075 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002076 Use openssl program to confirm three components are recoverable from a
2077 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002078 """
2079 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002080 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002081 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2082 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002083 self.assertEqual(recovered_key[-len(key):], key)
2084 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002085 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002086 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2087 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002088 self.assertEqual(recovered_cert[-len(cert):], cert)
2089 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002090 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002091 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2092 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002093 self.assertEqual(recovered_cert[-len(ca):], ca)
2094
Stephen Holsapple38482622014-04-05 20:29:34 -07002095 def verify_pkcs12_container(self, p12):
2096 """
2097 Verify that the PKCS#12 container contains the correct client
2098 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002099
2100 :param p12: The PKCS12 instance to verify.
2101 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002102 """
2103 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2104 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002105 self.assertEqual(
2106 (client_cert_pem, client_key_pem, None),
2107 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002108
Rick Deanf94096c2009-07-18 14:23:06 -05002109 def test_load_pkcs12(self):
2110 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002111 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002112 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002113 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002114 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002115 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002116 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002117 pem,
2118 b"pkcs12",
2119 b"-export",
2120 b"-clcerts",
2121 b"-passout",
2122 b"pass:" + passwd
2123 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002124 p12 = load_pkcs12(p12_str, passphrase=passwd)
2125 self.verify_pkcs12_container(p12)
2126
Abraham Martinc5484ba2015-03-25 15:33:05 +00002127 def test_load_pkcs12_text_passphrase(self):
2128 """
2129 A PKCS12 string generated using the openssl command line can be loaded
2130 with :py:obj:`load_pkcs12` and its components extracted and examined.
2131 Using text as passphrase instead of bytes. DeprecationWarning expected.
2132 """
2133 pem = client_key_pem + client_cert_pem
2134 passwd = b"whatever"
2135 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2136 b"-passout", b"pass:" + passwd)
2137 with catch_warnings(record=True) as w:
2138 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002139 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002140
2141 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002142 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002143 WARNING_TYPE_EXPECTED
2144 ),
2145 str(w[-1].message)
2146 )
2147 self.assertIs(w[-1].category, DeprecationWarning)
2148
Abraham Martinc5484ba2015-03-25 15:33:05 +00002149 self.verify_pkcs12_container(p12)
2150
Stephen Holsapple38482622014-04-05 20:29:34 -07002151 def test_load_pkcs12_no_passphrase(self):
2152 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002153 A PKCS12 string generated using openssl command line can be loaded with
2154 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2155 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002156 """
2157 pem = client_key_pem + client_cert_pem
2158 p12_str = _runopenssl(
2159 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2160 p12 = load_pkcs12(p12_str)
2161 self.verify_pkcs12_container(p12)
2162
Stephen Holsapple38482622014-04-05 20:29:34 -07002163 def _dump_and_load(self, dump_passphrase, load_passphrase):
2164 """
2165 A helper method to dump and load a PKCS12 object.
2166 """
2167 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2168 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2169 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2170
Stephen Holsapple38482622014-04-05 20:29:34 -07002171 def test_load_pkcs12_null_passphrase_load_empty(self):
2172 """
2173 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002174 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002175 extracted and examined.
2176 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002177 self.verify_pkcs12_container(
2178 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002179
Stephen Holsapple38482622014-04-05 20:29:34 -07002180 def test_load_pkcs12_null_passphrase_load_null(self):
2181 """
2182 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002183 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002184 extracted and examined.
2185 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002186 self.verify_pkcs12_container(
2187 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002188
Stephen Holsapple38482622014-04-05 20:29:34 -07002189 def test_load_pkcs12_empty_passphrase_load_empty(self):
2190 """
2191 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002192 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002193 extracted and examined.
2194 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002195 self.verify_pkcs12_container(
2196 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002197
Stephen Holsapple38482622014-04-05 20:29:34 -07002198 def test_load_pkcs12_empty_passphrase_load_null(self):
2199 """
2200 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002201 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002202 extracted and examined.
2203 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002204 self.verify_pkcs12_container(
2205 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002206
Rick Deanee568302009-07-24 09:56:29 -05002207 def test_load_pkcs12_garbage(self):
2208 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002209 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2210 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002211 """
2212 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002213 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002214 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2215 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002216
Rick Deanf94096c2009-07-18 14:23:06 -05002217 def test_replace(self):
2218 """
Alex Gaynor31287502015-09-05 16:11:27 -04002219 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2220 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002221 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002222 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002223 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2224 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2225 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002226 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002227 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002228 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002229 self.assertEqual(1, len(p12.get_ca_certificates()))
2230 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002231 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002232 self.assertEqual(2, len(p12.get_ca_certificates()))
2233 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2234 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2235
Rick Deanf94096c2009-07-18 14:23:06 -05002236 def test_friendly_name(self):
2237 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002238 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002239 :py:obj:`PKCS12.get_friendlyname` and
2240 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2241 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002242 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002243 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002244 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002245 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002246 p12.set_friendlyname(friendly_name)
2247 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002248 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002249 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002250 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002251 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002252 # We would use the openssl program to confirm the friendly
2253 # name, but it is not possible. The pkcs12 command
2254 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002255 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002256 self.check_recovery(
2257 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2258 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002259
Rick Deanf94096c2009-07-18 14:23:06 -05002260 def test_various_empty_passphrases(self):
2261 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002262 Test that missing, None, and '' passphrases are identical for PKCS12
2263 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002264 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002265 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002266 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002267 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2268 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2269 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2270 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2271 self.check_recovery(
2272 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2273 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002274
Rick Deanf94096c2009-07-18 14:23:06 -05002275 def test_removing_ca_cert(self):
2276 """
Alex Gaynor31287502015-09-05 16:11:27 -04002277 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2278 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002279 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002280 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2281 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002282 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002283
Rick Deanf94096c2009-07-18 14:23:06 -05002284 def test_export_without_mac(self):
2285 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002286 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002287 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002288 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002289 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002290 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002291 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002292 self.check_recovery(
2293 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002294 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002295
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002296 def test_load_without_mac(self):
2297 """
2298 Loading a PKCS12 without a MAC does something other than crash.
2299 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002300 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002301 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2302 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002303 try:
2304 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2305 # The person who generated this PCKS12 should be flogged,
2306 # or better yet we should have a means to determine
2307 # whether a PCKS12 had a MAC that was verified.
2308 # Anyway, libopenssl chooses to allow it, so the
2309 # pyopenssl binding does as well.
2310 self.assertTrue(isinstance(recovered_p12, PKCS12))
2311 except Error:
2312 # Failing here with an exception is preferred as some openssl
2313 # versions do.
2314 pass
Rick Dean623ee362009-07-17 12:22:16 -05002315
Rick Dean25bcc1f2009-07-20 11:53:13 -05002316 def test_zero_len_list_for_ca(self):
2317 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002318 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002319 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002320 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002321 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002322 p12.set_ca_certificates([])
2323 self.assertEqual((), p12.get_ca_certificates())
2324 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2325 self.check_recovery(
2326 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2327 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002328
Rick Deanf94096c2009-07-18 14:23:06 -05002329 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002330 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002331 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002332 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002333 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002334 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002335 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002336 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002337
Abraham Martinc5484ba2015-03-25 15:33:05 +00002338 def test_export_without_bytes(self):
2339 """
2340 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2341 """
2342 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2343
2344 with catch_warnings(record=True) as w:
2345 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002346 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002347 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002348 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002349 WARNING_TYPE_EXPECTED
2350 ),
2351 str(w[-1].message)
2352 )
2353 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002354 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002355 dumped_p12,
2356 key=server_key_pem,
2357 cert=server_cert_pem,
2358 passwd=b"randomtext"
2359 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002360
Rick Deanf94096c2009-07-18 14:23:06 -05002361 def test_key_cert_mismatch(self):
2362 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002363 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002364 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002365 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002366 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2367 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002368
2369
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002370# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002371_cmdLineQuoteRe = re.compile(br'(\\*)"')
2372_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002373
2374
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002375def cmdLineQuote(s):
2376 """
2377 Internal method for quoting a single command-line argument.
2378
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002379 See http://www.perlmonks.org/?node_id=764004
2380
Jonathan Ballet648875f2011-07-16 14:14:58 +09002381 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002382 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002383 cmd.exe-style quoting
2384
Jonathan Ballet648875f2011-07-16 14:14:58 +09002385 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002386 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002387 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002388 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2389 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002390
2391
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002392def quoteArguments(arguments):
2393 """
2394 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002395 a similar API. This allows the list passed to
2396 :py:obj:`reactor.spawnProcess` to match the child process's
2397 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002398
Jonathan Ballet648875f2011-07-16 14:14:58 +09002399 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002400 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002401
Jonathan Ballet648875f2011-07-16 14:14:58 +09002402 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002403 :return: A space-delimited string containing quoted versions of
2404 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002405 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002406 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002407
2408
Rick Dean4c9ad612009-07-17 15:05:22 -05002409def _runopenssl(pem, *args):
2410 """
2411 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002412 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002413 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002414 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002415 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002416 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2417 for arg in args
2418 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002419 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002420 command = b"openssl " + quoteArguments(args)
2421 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002422 proc.stdin.write(pem)
2423 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002424 output = proc.stdout.read()
2425 proc.stdout.close()
2426 proc.wait()
2427 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002428
2429
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002430class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002431 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002432 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002433 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002434
2435 def test_load_privatekey_invalid_format(self):
2436 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002437 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2438 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002439 """
2440 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2441
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002442 def test_load_privatekey_invalid_passphrase_type(self):
2443 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002444 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2445 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002446 """
2447 self.assertRaises(
2448 TypeError,
2449 load_privatekey,
2450 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2451
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002452 def test_load_privatekey_wrong_args(self):
2453 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002454 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2455 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002456 """
2457 self.assertRaises(TypeError, load_privatekey)
2458
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002459 def test_load_privatekey_wrongPassphrase(self):
2460 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002461 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2462 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002463 """
2464 self.assertRaises(
2465 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002466 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002467
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002468 def test_load_privatekey_passphraseWrongType(self):
2469 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002470 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2471 a passphrase with a private key encoded in a format, that doesn't
2472 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002473 """
2474 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2475 blob = dump_privatekey(FILETYPE_ASN1, key)
2476 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002477 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002478
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002479 def test_load_privatekey_passphrase(self):
2480 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002481 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2482 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002483 """
2484 key = load_privatekey(
2485 FILETYPE_PEM, encryptedPrivateKeyPEM,
2486 encryptedPrivateKeyPEMPassphrase)
2487 self.assertTrue(isinstance(key, PKeyType))
2488
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002489 def test_load_privatekey_passphrase_exception(self):
2490 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002491 If the passphrase callback raises an exception, that exception is
2492 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002493 """
2494 def cb(ignored):
2495 raise ArithmeticError
2496
Alex Gaynor791212d2015-09-05 15:46:08 -04002497 with pytest.raises(ArithmeticError):
2498 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002499
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002500 def test_load_privatekey_wrongPassphraseCallback(self):
2501 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002502 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2503 is passed an encrypted PEM and a passphrase callback which returns an
2504 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002505 """
2506 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002507
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002508 def cb(*a):
2509 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002510 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002511 self.assertRaises(
2512 Error,
2513 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2514 self.assertTrue(called)
2515
2516 def test_load_privatekey_passphraseCallback(self):
2517 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002518 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2519 encrypted PEM string if given a passphrase callback which returns the
2520 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002521 """
2522 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002523
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002524 def cb(writing):
2525 called.append(writing)
2526 return encryptedPrivateKeyPEMPassphrase
2527 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2528 self.assertTrue(isinstance(key, PKeyType))
2529 self.assertEqual(called, [False])
2530
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002531 def test_load_privatekey_passphrase_wrong_return_type(self):
2532 """
2533 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2534 callback returns something other than a byte string.
2535 """
2536 self.assertRaises(
2537 ValueError,
2538 load_privatekey,
2539 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2540
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002541 def test_dump_privatekey_wrong_args(self):
2542 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002543 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2544 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002545 """
2546 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002547 # If cipher name is given, password is required.
2548 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002549 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002550
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002551 def test_dump_privatekey_unknown_cipher(self):
2552 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002553 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2554 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002555 """
2556 key = PKey()
2557 key.generate_key(TYPE_RSA, 512)
2558 self.assertRaises(
2559 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002560 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002561
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002562 def test_dump_privatekey_invalid_passphrase_type(self):
2563 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002564 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2565 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002566 """
2567 key = PKey()
2568 key.generate_key(TYPE_RSA, 512)
2569 self.assertRaises(
2570 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002571 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002572
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002573 def test_dump_privatekey_invalid_filetype(self):
2574 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002575 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2576 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002577 """
2578 key = PKey()
2579 key.generate_key(TYPE_RSA, 512)
2580 self.assertRaises(ValueError, dump_privatekey, 100, key)
2581
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002582 def test_load_privatekey_passphraseCallbackLength(self):
2583 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002584 :py:obj:`crypto.load_privatekey` should raise an error when the
2585 passphrase provided by the callback is too long, not silently truncate
2586 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002587 """
2588 def cb(ignored):
2589 return "a" * 1025
2590
Alex Gaynor791212d2015-09-05 15:46:08 -04002591 with pytest.raises(ValueError):
2592 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002593
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002594 def test_dump_privatekey_passphrase(self):
2595 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002596 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2597 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002598 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002599 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002600 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002601 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2602 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002603 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2604 self.assertTrue(isinstance(loadedKey, PKeyType))
2605 self.assertEqual(loadedKey.type(), key.type())
2606 self.assertEqual(loadedKey.bits(), key.bits())
2607
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002608 def test_dump_privatekey_passphraseWrongType(self):
2609 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002610 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2611 a passphrase with a private key encoded in a format, that doesn't
2612 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002613 """
2614 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002615 with pytest.raises(ValueError):
2616 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002617
Rick Dean5b7b6372009-04-01 11:34:06 -05002618 def test_dump_certificate(self):
2619 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002620 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002621 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002622 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002623 cert = load_certificate(FILETYPE_PEM, pemData)
2624 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2625 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2626 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002627 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002628 self.assertEqual(dumped_der, good_der)
2629 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2630 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2631 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2632 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002633 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002634 self.assertEqual(dumped_text, good_text)
2635
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002636 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002637 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002638 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002639 """
2640 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002641 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002642 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2643 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002644
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002645 def test_dump_privatekey_asn1(self):
2646 """
2647 :py:obj:`dump_privatekey` writes a DER
2648 """
2649 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2650 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2651
Rick Dean5b7b6372009-04-01 11:34:06 -05002652 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002653 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002654 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002655 self.assertEqual(dumped_der, good_der)
2656 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2657 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2658 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002659
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002660 def test_dump_privatekey_text(self):
2661 """
2662 :py:obj:`dump_privatekey` writes a text
2663 """
2664 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2665 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2666
Rick Dean5b7b6372009-04-01 11:34:06 -05002667 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002668 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002669 self.assertEqual(dumped_text, good_text)
2670
Cory Benfield6492f7c2015-10-27 16:57:58 +09002671 def test_dump_publickey_pem(self):
2672 """
Cory Benfield11c10192015-10-27 17:23:03 +09002673 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002674 """
2675 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2676 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002677 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002678
2679 def test_dump_publickey_asn1(self):
2680 """
Cory Benfield11c10192015-10-27 17:23:03 +09002681 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002682 """
2683 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2684 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2685 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2686 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002687 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002688
Cory Benfielde02c7d82015-10-27 17:34:49 +09002689 def test_dump_publickey_invalid_type(self):
2690 """
2691 dump_publickey doesn't support FILETYPE_TEXT.
2692 """
2693 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2694
2695 with pytest.raises(ValueError):
2696 dump_publickey(FILETYPE_TEXT, key)
2697
2698 def test_load_publickey_invalid_type(self):
2699 """
2700 load_publickey doesn't support FILETYPE_TEXT.
2701 """
2702 with pytest.raises(ValueError):
2703 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2704
2705 def test_load_publickey_invalid_key_format(self):
2706 """
2707 load_publickey explodes on incorrect keys.
2708 """
2709 with pytest.raises(Error):
2710 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2711
2712 def test_load_publickey_tolerates_unicode_strings(self):
2713 """
2714 load_publickey works with text strings, not just bytes.
2715 """
2716 serialized = cleartextPublicKeyPEM.decode('ascii')
2717 key = load_publickey(FILETYPE_PEM, serialized)
2718 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2719 assert dumped_pem == cleartextPublicKeyPEM
2720
Rick Dean5b7b6372009-04-01 11:34:06 -05002721 def test_dump_certificate_request(self):
2722 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002723 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002724 """
Alex Gaynor31287502015-09-05 16:11:27 -04002725 req = load_certificate_request(
2726 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002727 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2728 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2729 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002730 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002731 self.assertEqual(dumped_der, good_der)
2732 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2733 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2734 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2735 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002736 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002737 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002738 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002739
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002740 def test_dump_privatekey_passphraseCallback(self):
2741 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002742 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2743 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002744 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002745 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002746 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002747
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002748 def cb(writing):
2749 called.append(writing)
2750 return passphrase
2751 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002752 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2753 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002754 self.assertEqual(called, [True])
2755 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2756 self.assertTrue(isinstance(loadedKey, PKeyType))
2757 self.assertEqual(loadedKey.type(), key.type())
2758 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002759
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002760 def test_dump_privatekey_passphrase_exception(self):
2761 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002762 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002763 by the passphrase callback.
2764 """
2765 def cb(ignored):
2766 raise ArithmeticError
2767
2768 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002769 with pytest.raises(ArithmeticError):
2770 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002771
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002772 def test_dump_privatekey_passphraseCallbackLength(self):
2773 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002774 :py:obj:`crypto.dump_privatekey` should raise an error when the
2775 passphrase provided by the callback is too long, not silently truncate
2776 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002777 """
2778 def cb(ignored):
2779 return "a" * 1025
2780
2781 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002782 with pytest.raises(ValueError):
2783 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002784
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002785 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002786 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002787 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2788 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002789 """
2790 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2791 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2792
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002793 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002794 """
2795 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2796 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2797 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002798 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2799 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2800
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002801 def test_load_pkcs7_data_invalid(self):
2802 """
2803 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2804 :py:obj:`Error` is raised.
2805 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002806 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002807
2808
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002809class LoadCertificateTests(TestCase):
2810 """
2811 Tests for :py:obj:`load_certificate_request`.
2812 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002813
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002814 def test_badFileType(self):
2815 """
2816 If the file type passed to :py:obj:`load_certificate_request` is
2817 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2818 :py:class:`ValueError` is raised.
2819 """
2820 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2821
2822
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002823class PKCS7Tests(TestCase):
2824 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002825 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002826 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002827
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002828 def test_type(self):
2829 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002830 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002831 """
2832 self.assertTrue(isinstance(PKCS7Type, type))
2833 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2834
2835 # XXX This doesn't currently work.
2836 # self.assertIdentical(PKCS7, PKCS7Type)
2837
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002838 # XXX Opposite results for all these following methods
2839
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002840 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002841 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002842 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2843 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002844 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002845 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2846 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2847
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002848 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002849 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002850 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2851 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002852 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002853 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2854 self.assertTrue(pkcs7.type_is_signed())
2855
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002856 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002857 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002858 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2859 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002860 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002861 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2862 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2863
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002864 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002865 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002866 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2867 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002868 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002869 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2870 self.assertFalse(pkcs7.type_is_enveloped())
2871
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002872 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002873 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002874 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2875 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002876 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002877 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2878 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2879
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002880 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002881 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002882 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2883 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002884 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002885 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2886 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2887
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002888 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002889 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002890 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2891 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002892 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002893 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2894 self.assertFalse(pkcs7.type_is_data())
2895
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002896 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002897 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002898 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2899 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002900 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002901 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2902 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2903
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002904 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002905 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002906 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2907 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002908 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002909 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2910 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2911
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002912 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002913 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002914 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2915 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002916 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002917 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002918 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002919
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002920 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002921 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002922 If an attribute other than one of the methods tested here is accessed
2923 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2924 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002925 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002926 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2927 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2928
2929
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002930class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002931 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002932 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002933 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002934
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002935 def signable(self):
2936 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002937 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002938 """
2939 return NetscapeSPKI()
2940
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002941 def test_type(self):
2942 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002943 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2944 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002945 """
2946 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2947 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2948
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002949 def test_construction(self):
2950 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002951 :py:obj:`NetscapeSPKI` returns an instance of
2952 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002953 """
2954 nspki = NetscapeSPKI()
2955 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2956
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002957 def test_invalid_attribute(self):
2958 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002959 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2960 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002961 """
2962 nspki = NetscapeSPKI()
2963 self.assertRaises(AttributeError, lambda: nspki.foo)
2964
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002965 def test_b64_encode(self):
2966 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002967 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2968 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002969 """
2970 nspki = NetscapeSPKI()
2971 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002972 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002973
2974
Paul Kehrer2c605ba2016-03-11 11:17:26 -04002975class TestRevoked(object):
2976 """
2977 Please add test cases for the Revoked class here if possible. This class
2978 holds the new py.test style tests.
2979 """
2980 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
2981 """
2982 The get_reason method on the Revoked class checks to see if the
2983 extension is NID_crl_reason and should skip it otherwise. This test
2984 loads a CRL with extensions it should ignore.
2985 """
2986 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
2987 revoked = crl.get_revoked()
2988 reason = revoked[1].get_reason()
2989 assert reason == b'Unspecified'
2990
2991 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
2992 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
2993 revoked = crl.get_revoked()
2994 revoked[1].set_reason(None)
2995 reason = revoked[1].get_reason()
2996 assert reason is None
2997
2998
Rick Dean536ba022009-07-24 23:57:27 -05002999class RevokedTests(TestCase):
3000 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003001 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3002 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003003 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003004
Rick Dean536ba022009-07-24 23:57:27 -05003005 def test_construction(self):
3006 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003007 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003008 that it is empty.
3009 """
3010 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003011 self.assertTrue(isinstance(revoked, Revoked))
3012 self.assertEquals(type(revoked), Revoked)
3013 self.assertEquals(revoked.get_serial(), b('00'))
3014 self.assertEquals(revoked.get_rev_date(), None)
3015 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003016
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003017 def test_construction_wrong_args(self):
3018 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003019 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3020 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003021 """
3022 self.assertRaises(TypeError, Revoked, None)
3023 self.assertRaises(TypeError, Revoked, 1)
3024 self.assertRaises(TypeError, Revoked, "foo")
3025
Rick Dean536ba022009-07-24 23:57:27 -05003026 def test_serial(self):
3027 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003028 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003029 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003030 with grace.
3031 """
3032 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003033 ret = revoked.set_serial(b('10b'))
3034 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003035 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003036 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003037
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003038 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003039 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003040 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003041
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003042 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003043 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003044 self.assertRaises(TypeError, revoked.get_serial, 1)
3045 self.assertRaises(TypeError, revoked.get_serial, None)
3046 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003047
Rick Dean536ba022009-07-24 23:57:27 -05003048 def test_date(self):
3049 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003050 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003051 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003052 with grace.
3053 """
3054 revoked = Revoked()
3055 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003056 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003057
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003058 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003059 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003060 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003061 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003062 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003063
Rick Dean6385faf2009-07-26 00:07:47 -05003064 def test_reason(self):
3065 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003066 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003067 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003068 as "set". Likewise, each reason of all_reasons() must work.
3069 """
3070 revoked = Revoked()
3071 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003072 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003073 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003074 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003075 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003076 self.assertEquals(
3077 reason.lower().replace(b(' '), b('')),
3078 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003079 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003080
3081 revoked.set_reason(None)
3082 self.assertEqual(revoked.get_reason(), None)
3083
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003084 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003085 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003086 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003087 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003088 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003089 """
3090 revoked = Revoked()
3091 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003092 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003093
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003094 def test_get_reason_wrong_arguments(self):
3095 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003096 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3097 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003098 """
3099 revoked = Revoked()
3100 self.assertRaises(TypeError, revoked.get_reason, None)
3101 self.assertRaises(TypeError, revoked.get_reason, 1)
3102 self.assertRaises(TypeError, revoked.get_reason, "foo")
3103
3104
Rick Dean536ba022009-07-24 23:57:27 -05003105class CRLTests(TestCase):
3106 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003107 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003108 """
3109 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3110 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3111
3112 def test_construction(self):
3113 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003114 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003115 that it is empty
3116 """
3117 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003118 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003119 self.assertEqual(crl.get_revoked(), None)
3120
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003121 def test_construction_wrong_args(self):
3122 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003123 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3124 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003125 """
3126 self.assertRaises(TypeError, CRL, 1)
3127 self.assertRaises(TypeError, CRL, "")
3128 self.assertRaises(TypeError, CRL, None)
3129
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003130 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003131 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003132 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003133 """
3134 crl = CRL()
3135 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003136 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003137 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003138 revoked.set_serial(b('3ab'))
3139 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003140 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003141 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003142
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003143 def test_export_pem(self):
3144 """
3145 If not passed a format, ``CRL.export`` returns a "PEM" format string
3146 representing a serial number, a revoked reason, and certificate issuer
3147 information.
3148 """
3149 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003150 # PEM format
3151 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003152 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003153
3154 # These magic values are based on the way the CRL above was constructed
3155 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003156 text.index(b('Serial Number: 03AB'))
3157 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003158 text.index(
3159 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3160 )
3161
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003162 def test_export_der(self):
3163 """
3164 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3165 "DER" format string representing a serial number, a revoked reason, and
3166 certificate issuer information.
3167 """
3168 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003169
3170 # DER format
3171 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003172 text = _runopenssl(
3173 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3174 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003175 text.index(b('Serial Number: 03AB'))
3176 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003177 text.index(
3178 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3179 )
3180
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003181 def test_export_text(self):
3182 """
3183 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3184 text format string like the one produced by the openssl command line
3185 tool.
3186 """
3187 crl = self._get_crl()
3188
3189 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3190 text = _runopenssl(
3191 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3192 )
Rick Dean536ba022009-07-24 23:57:27 -05003193
3194 # text format
3195 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3196 self.assertEqual(text, dumped_text)
3197
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003198 def test_export_custom_digest(self):
3199 """
3200 If passed the name of a digest function, ``CRL.export`` uses a
3201 signature algorithm based on that digest function.
3202 """
3203 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003204 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003205 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3206 text.index(b('Signature Algorithm: sha1'))
3207
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003208 def test_export_md5_digest(self):
3209 """
3210 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3211 not emit a deprecation warning.
3212 """
3213 crl = self._get_crl()
3214 with catch_warnings(record=True) as catcher:
3215 simplefilter("always")
3216 self.assertEqual(0, len(catcher))
3217 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3218 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3219 text.index(b('Signature Algorithm: md5'))
3220
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003221 def test_export_default_digest(self):
3222 """
3223 If not passed the name of a digest function, ``CRL.export`` uses a
3224 signature algorithm based on MD5 and emits a deprecation warning.
3225 """
3226 crl = self._get_crl()
3227 with catch_warnings(record=True) as catcher:
3228 simplefilter("always")
3229 dumped_crl = crl.export(self.cert, self.pkey)
3230 self.assertEqual(
3231 "The default message digest (md5) is deprecated. "
3232 "Pass the name of a message digest explicitly.",
3233 str(catcher[0].message),
3234 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003235 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3236 text.index(b('Signature Algorithm: md5'))
3237
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003238 def test_export_invalid(self):
3239 """
3240 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003241 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003242 """
3243 crl = CRL()
3244 self.assertRaises(Error, crl.export, X509(), PKey())
3245
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003246 def test_add_revoked_keyword(self):
3247 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003248 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003249 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003250 """
3251 crl = CRL()
3252 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003253 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003254 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003255 crl.add_revoked(revoked=revoked)
3256 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3257
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003258 def test_export_wrong_args(self):
3259 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003260 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003261 four arguments, or with arguments other than the certificate,
3262 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003263 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003264 """
3265 crl = CRL()
3266 self.assertRaises(TypeError, crl.export)
3267 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003268 with pytest.raises(TypeError):
3269 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3270 with pytest.raises(TypeError):
3271 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3272 with pytest.raises(TypeError):
3273 crl.export(self.cert, None, FILETYPE_PEM, 10)
3274 with pytest.raises(TypeError):
3275 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003276 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3277
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003278 def test_export_unknown_filetype(self):
3279 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003280 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003281 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3282 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003283 """
3284 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003285 with pytest.raises(ValueError):
3286 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003287
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003288 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003289 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003290 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003291 in a :py:obj:`ValueError` being raised.
3292 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003293 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003294 self.assertRaises(
3295 ValueError,
3296 crl.export,
3297 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3298 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003299
Rick Dean536ba022009-07-24 23:57:27 -05003300 def test_get_revoked(self):
3301 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003302 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003303 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3304 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003305 """
3306 crl = CRL()
3307
3308 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003309 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003310 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003311 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003312 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003313 revoked.set_serial(b('100'))
3314 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003315 crl.add_revoked(revoked)
3316
3317 revs = crl.get_revoked()
3318 self.assertEqual(len(revs), 2)
3319 self.assertEqual(type(revs[0]), Revoked)
3320 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003321 self.assertEqual(revs[0].get_serial(), b('03AB'))
3322 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003323 self.assertEqual(revs[0].get_rev_date(), now)
3324 self.assertEqual(revs[1].get_rev_date(), now)
3325
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003326 def test_get_revoked_wrong_args(self):
3327 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003328 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3329 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003330 """
3331 crl = CRL()
3332 self.assertRaises(TypeError, crl.get_revoked, None)
3333 self.assertRaises(TypeError, crl.get_revoked, 1)
3334 self.assertRaises(TypeError, crl.get_revoked, "")
3335 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3336
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003337 def test_add_revoked_wrong_args(self):
3338 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003339 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3340 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003341 """
3342 crl = CRL()
3343 self.assertRaises(TypeError, crl.add_revoked)
3344 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3345 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3346
Rick Dean536ba022009-07-24 23:57:27 -05003347 def test_load_crl(self):
3348 """
3349 Load a known CRL and inspect its revocations. Both
3350 PEM and DER formats are loaded.
3351 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003352 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003353 revs = crl.get_revoked()
3354 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003355 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003356 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003357 self.assertEqual(revs[1].get_serial(), b('0100'))
3358 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003359
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003360 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003361 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003362 revs = crl.get_revoked()
3363 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003364 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003365 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003366 self.assertEqual(revs[1].get_serial(), b('0100'))
3367 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003368
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003369 def test_load_crl_wrong_args(self):
3370 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003371 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3372 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003373 """
3374 self.assertRaises(TypeError, load_crl)
3375 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3376 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3377
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003378 def test_load_crl_bad_filetype(self):
3379 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003380 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3381 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003382 """
3383 self.assertRaises(ValueError, load_crl, 100, crlData)
3384
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003385 def test_load_crl_bad_data(self):
3386 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003387 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3388 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003389 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003390 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003391
Dominic Chenf05b2122015-10-13 16:32:35 +00003392 def test_dump_crl(self):
3393 """
3394 The dumped CRL matches the original input.
3395 """
3396 crl = load_crl(FILETYPE_PEM, crlData)
3397 buf = dump_crl(FILETYPE_PEM, crl)
3398 assert buf == crlData
3399
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003400
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003401class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003402 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003403 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003404 """
3405 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3406 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003407 intermediate_server_cert = load_certificate(
3408 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003409
3410 def test_valid(self):
3411 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003412 :py:obj:`verify_certificate` returns ``None`` when called with a
3413 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003414 """
3415 store = X509Store()
3416 store.add_cert(self.root_cert)
3417 store.add_cert(self.intermediate_cert)
3418 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003419 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003420
3421 def test_reuse(self):
3422 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003423 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003424 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003425 """
3426 store = X509Store()
3427 store.add_cert(self.root_cert)
3428 store.add_cert(self.intermediate_cert)
3429 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003430 self.assertEqual(store_ctx.verify_certificate(), None)
3431 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003432
3433 def test_trusted_self_signed(self):
3434 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003435 :py:obj:`verify_certificate` returns ``None`` when called with a
3436 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003437 """
3438 store = X509Store()
3439 store.add_cert(self.root_cert)
3440 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003441 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003442
3443 def test_untrusted_self_signed(self):
3444 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003445 :py:obj:`verify_certificate` raises error when a self-signed
3446 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003447 """
3448 store = X509Store()
3449 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003450 with pytest.raises(X509StoreContextError) as exc:
3451 store_ctx.verify_certificate()
3452
3453 assert exc.value.args[0][2] == 'self signed certificate'
3454 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003455
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003456 def test_invalid_chain_no_root(self):
3457 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003458 :py:obj:`verify_certificate` raises error when a root certificate is
3459 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003460 """
3461 store = X509Store()
3462 store.add_cert(self.intermediate_cert)
3463 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003464
3465 with pytest.raises(X509StoreContextError) as exc:
3466 store_ctx.verify_certificate()
3467
3468 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3469 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003470
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003471 def test_invalid_chain_no_intermediate(self):
3472 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003473 :py:obj:`verify_certificate` raises error when an intermediate
3474 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003475 """
3476 store = X509Store()
3477 store.add_cert(self.root_cert)
3478 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003479
Alex Gaynor85b49702015-09-05 16:30:59 -04003480 with pytest.raises(X509StoreContextError) as exc:
3481 store_ctx.verify_certificate()
3482
3483 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3484 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003485
Stephen Holsapple46a09252015-02-12 14:45:43 -08003486 def test_modification_pre_verify(self):
3487 """
3488 :py:obj:`verify_certificate` can use a store context modified after
3489 instantiation.
3490 """
3491 store_bad = X509Store()
3492 store_bad.add_cert(self.intermediate_cert)
3493 store_good = X509Store()
3494 store_good.add_cert(self.root_cert)
3495 store_good.add_cert(self.intermediate_cert)
3496 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003497
3498 with pytest.raises(X509StoreContextError) as exc:
3499 store_ctx.verify_certificate()
3500
3501 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3502 assert exc.value.certificate.get_subject().CN == 'intermediate'
3503
Stephen Holsapple46a09252015-02-12 14:45:43 -08003504 store_ctx.set_store(store_good)
3505 self.assertEqual(store_ctx.verify_certificate(), None)
3506
3507
James Yonan7c2e5d32010-02-27 05:45:50 -07003508class SignVerifyTests(TestCase):
3509 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003510 Tests for :py:obj:`OpenSSL.crypto.sign` and
3511 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003512 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003513
James Yonan7c2e5d32010-02-27 05:45:50 -07003514 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003515 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003516 :py:obj:`sign` generates a cryptographic signature which
3517 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003518 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003519 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003520 "It was a bright cold day in April, and the clocks were striking "
3521 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3522 "effort to escape the vile wind, slipped quickly through the "
3523 "glass doors of Victory Mansions, though not quickly enough to "
3524 "prevent a swirl of gritty dust from entering along with him.")
3525
3526 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003527 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003528 # verify the content with this cert
3529 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3530 # certificate unrelated to priv_key, used to trigger an error
3531 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003532
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003533 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003534 sig = sign(priv_key, content, digest)
3535
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003536 # Verify the signature of content, will throw an exception if
3537 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003538 verify(good_cert, sig, content, digest)
3539
3540 # This should fail because the certificate doesn't match the
3541 # private key that was used to sign the content.
3542 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3543
3544 # This should fail because we've "tainted" the content after
3545 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003546 self.assertRaises(
3547 Error, verify,
3548 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003549
3550 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003551 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003552 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003553 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003554 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003555
Abraham Martinc5484ba2015-03-25 15:33:05 +00003556 def test_sign_verify_with_text(self):
3557 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003558 :py:obj:`sign` generates a cryptographic signature which
3559 :py:obj:`verify` can check. Deprecation warnings raised because using
3560 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003561 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003562 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003563 b"It was a bright cold day in April, and the clocks were striking "
3564 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3565 b"effort to escape the vile wind, slipped quickly through the "
3566 b"glass doors of Victory Mansions, though not quickly enough to "
3567 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003568 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003569
3570 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3571 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3572 for digest in ['md5', 'sha1']:
3573 with catch_warnings(record=True) as w:
3574 simplefilter("always")
3575 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003576
3577 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003578 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003579 WARNING_TYPE_EXPECTED
3580 ),
3581 str(w[-1].message)
3582 )
3583 self.assertIs(w[-1].category, DeprecationWarning)
3584
Abraham Martinc5484ba2015-03-25 15:33:05 +00003585 with catch_warnings(record=True) as w:
3586 simplefilter("always")
3587 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003588
3589 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003590 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003591 WARNING_TYPE_EXPECTED
3592 ),
3593 str(w[-1].message)
3594 )
3595 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003596
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003597 def test_sign_nulls(self):
3598 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003599 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003600 """
3601 content = b("Watch out! \0 Did you see it?")
3602 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3603 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3604 sig = sign(priv_key, content, "sha1")
3605 verify(good_cert, sig, content, "sha1")
3606
Colleen Murphye09399b2016-03-01 17:40:49 -08003607 def test_sign_with_large_key(self):
3608 """
3609 :py:obj:`sign` produces a signature for a string when using a long key.
3610 """
3611 content = b(
3612 "It was a bright cold day in April, and the clocks were striking "
3613 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3614 "effort to escape the vile wind, slipped quickly through the "
3615 "glass doors of Victory Mansions, though not quickly enough to "
3616 "prevent a swirl of gritty dust from entering along with him.")
3617
3618 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3619 sign(priv_key, content, "sha1")
3620
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003621
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003622class EllipticCurveTests(TestCase):
3623 """
3624 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3625 :py:obj:`get_elliptic_curves`.
3626 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003627
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003628 def test_set(self):
3629 """
3630 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3631 """
3632 self.assertIsInstance(get_elliptic_curves(), set)
3633
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003634 def test_some_curves(self):
3635 """
3636 If :py:mod:`cryptography` has elliptic curve support then the set
3637 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3638 it.
3639
3640 There could be an OpenSSL that violates this assumption. If so, this
3641 test will fail and we'll find out.
3642 """
3643 curves = get_elliptic_curves()
3644 if lib.Cryptography_HAS_EC:
3645 self.assertTrue(curves)
3646 else:
3647 self.assertFalse(curves)
3648
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003649 def test_a_curve(self):
3650 """
3651 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3652 supported curve.
3653 """
3654 curves = get_elliptic_curves()
3655 if curves:
3656 curve = next(iter(curves))
3657 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3658 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003659 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003660
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003661 def test_not_a_curve(self):
3662 """
3663 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3664 with a name which does not identify a supported curve.
3665 """
3666 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003667 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003668
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003669 def test_repr(self):
3670 """
3671 The string representation of a curve object includes simply states the
3672 object is a curve and what its name is.
3673 """
3674 curves = get_elliptic_curves()
3675 if curves:
3676 curve = next(iter(curves))
3677 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3678
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003679 def test_to_EC_KEY(self):
3680 """
3681 The curve object can export a version of itself as an EC_KEY* via the
3682 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3683 """
3684 curves = get_elliptic_curves()
3685 if curves:
3686 curve = next(iter(curves))
3687 # It's not easy to assert anything about this object. However, see
3688 # leakcheck/crypto.py for a test that demonstrates it at least does
3689 # not leak memory.
3690 curve._to_EC_KEY()
3691
3692
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003693class EllipticCurveFactory(object):
3694 """
3695 A helper to get the names of two curves.
3696 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003697
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003698 def __init__(self):
3699 curves = iter(get_elliptic_curves())
3700 try:
3701 self.curve_name = next(curves).name
3702 self.another_curve_name = next(curves).name
3703 except StopIteration:
3704 self.curve_name = self.another_curve_name = None
3705
3706
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003707class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3708 """
3709 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3710 """
3711 curve_factory = EllipticCurveFactory()
3712
3713 if curve_factory.curve_name is None:
3714 skip = "There are no curves available there can be no curve objects."
3715
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003716 def anInstance(self):
3717 """
3718 Get the curve object for an arbitrary curve supported by the system.
3719 """
3720 return get_elliptic_curve(self.curve_factory.curve_name)
3721
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003722 def anotherInstance(self):
3723 """
3724 Get the curve object for an arbitrary curve supported by the system -
3725 but not the one returned by C{anInstance}.
3726 """
3727 return get_elliptic_curve(self.curve_factory.another_curve_name)
3728
3729
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003730class EllipticCurveHashTests(TestCase):
3731 """
3732 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3733 as an item in a :py:type:`dict` or :py:type:`set`).
3734 """
3735 curve_factory = EllipticCurveFactory()
3736
3737 if curve_factory.curve_name is None:
3738 skip = "There are no curves available there can be no curve objects."
3739
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003740 def test_contains(self):
3741 """
3742 The ``in`` operator reports that a :py:type:`set` containing a curve
3743 does contain that curve.
3744 """
3745 curve = get_elliptic_curve(self.curve_factory.curve_name)
3746 curves = set([curve])
3747 self.assertIn(curve, curves)
3748
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003749 def test_does_not_contain(self):
3750 """
3751 The ``in`` operator reports that a :py:type:`set` not containing a
3752 curve does not contain that curve.
3753 """
3754 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003755 curves = set([
3756 get_elliptic_curve(self.curve_factory.another_curve_name)
3757 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003758 self.assertNotIn(curve, curves)
3759
3760
Rick Dean5b7b6372009-04-01 11:34:06 -05003761if __name__ == '__main__':
3762 main()