blob: d5cecad660c04fb8a2befd12d2b3aec2a4f5f54c [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
Rick Dean536ba022009-07-24 23:57:27 -05002975class RevokedTests(TestCase):
2976 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002977 Tests for :py:obj:`OpenSSL.crypto.Revoked`
Rick Dean536ba022009-07-24 23:57:27 -05002978 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002979
Rick Dean536ba022009-07-24 23:57:27 -05002980 def test_construction(self):
2981 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002982 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002983 that it is empty.
2984 """
2985 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002986 self.assertTrue(isinstance(revoked, Revoked))
2987 self.assertEquals(type(revoked), Revoked)
2988 self.assertEquals(revoked.get_serial(), b('00'))
2989 self.assertEquals(revoked.get_rev_date(), None)
2990 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05002991
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002992 def test_construction_wrong_args(self):
2993 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002994 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
2995 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002996 """
2997 self.assertRaises(TypeError, Revoked, None)
2998 self.assertRaises(TypeError, Revoked, 1)
2999 self.assertRaises(TypeError, Revoked, "foo")
3000
Rick Dean536ba022009-07-24 23:57:27 -05003001 def test_serial(self):
3002 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003003 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003004 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003005 with grace.
3006 """
3007 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003008 ret = revoked.set_serial(b('10b'))
3009 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003010 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003011 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003012
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003013 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003014 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003015 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003016
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003017 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003018 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003019 self.assertRaises(TypeError, revoked.get_serial, 1)
3020 self.assertRaises(TypeError, revoked.get_serial, None)
3021 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003022
Rick Dean536ba022009-07-24 23:57:27 -05003023 def test_date(self):
3024 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003025 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003026 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003027 with grace.
3028 """
3029 revoked = Revoked()
3030 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003031 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003032
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003033 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003034 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003035 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003036 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003037 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003038
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -04003039 def test_ignores_unsupported_revoked_cert_extension(self):
3040 """
3041 The get_reason method on the Revoked class checks to see if the
3042 extension is NID_crl_reason and should skip it otherwise. This test
3043 loads a CRL with extensions it should ignore.
3044 """
3045 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3046 revoked = crl.get_revoked()
Paul Kehrer418411e2016-03-11 10:31:33 -04003047 reason = revoked[1].get_reason()
Paul Kehrer5aad73c2016-03-11 10:39:42 -04003048 assert reason == b'Unspecified'
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -04003049
Rick Dean6385faf2009-07-26 00:07:47 -05003050 def test_reason(self):
3051 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003052 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003053 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003054 as "set". Likewise, each reason of all_reasons() must work.
3055 """
3056 revoked = Revoked()
3057 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003058 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003059 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003060 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003061 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003062 self.assertEquals(
3063 reason.lower().replace(b(' '), b('')),
3064 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003065 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003066
3067 revoked.set_reason(None)
3068 self.assertEqual(revoked.get_reason(), None)
3069
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003070 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003071 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003072 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003073 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003074 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003075 """
3076 revoked = Revoked()
3077 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003078 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003079
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003080 def test_get_reason_wrong_arguments(self):
3081 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003082 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3083 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003084 """
3085 revoked = Revoked()
3086 self.assertRaises(TypeError, revoked.get_reason, None)
3087 self.assertRaises(TypeError, revoked.get_reason, 1)
3088 self.assertRaises(TypeError, revoked.get_reason, "foo")
3089
3090
Rick Dean536ba022009-07-24 23:57:27 -05003091class CRLTests(TestCase):
3092 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003093 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003094 """
3095 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3096 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3097
3098 def test_construction(self):
3099 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003100 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003101 that it is empty
3102 """
3103 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003104 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003105 self.assertEqual(crl.get_revoked(), None)
3106
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003107 def test_construction_wrong_args(self):
3108 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003109 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3110 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003111 """
3112 self.assertRaises(TypeError, CRL, 1)
3113 self.assertRaises(TypeError, CRL, "")
3114 self.assertRaises(TypeError, CRL, None)
3115
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003116 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003117 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003118 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003119 """
3120 crl = CRL()
3121 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003122 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003123 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003124 revoked.set_serial(b('3ab'))
3125 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003126 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003127 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003128
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003129 def test_export_pem(self):
3130 """
3131 If not passed a format, ``CRL.export`` returns a "PEM" format string
3132 representing a serial number, a revoked reason, and certificate issuer
3133 information.
3134 """
3135 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003136 # PEM format
3137 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003138 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003139
3140 # These magic values are based on the way the CRL above was constructed
3141 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003142 text.index(b('Serial Number: 03AB'))
3143 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003144 text.index(
3145 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3146 )
3147
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003148 def test_export_der(self):
3149 """
3150 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3151 "DER" format string representing a serial number, a revoked reason, and
3152 certificate issuer information.
3153 """
3154 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003155
3156 # DER format
3157 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003158 text = _runopenssl(
3159 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3160 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003161 text.index(b('Serial Number: 03AB'))
3162 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003163 text.index(
3164 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3165 )
3166
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003167 def test_export_text(self):
3168 """
3169 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3170 text format string like the one produced by the openssl command line
3171 tool.
3172 """
3173 crl = self._get_crl()
3174
3175 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3176 text = _runopenssl(
3177 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3178 )
Rick Dean536ba022009-07-24 23:57:27 -05003179
3180 # text format
3181 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3182 self.assertEqual(text, dumped_text)
3183
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003184 def test_export_custom_digest(self):
3185 """
3186 If passed the name of a digest function, ``CRL.export`` uses a
3187 signature algorithm based on that digest function.
3188 """
3189 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003190 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003191 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3192 text.index(b('Signature Algorithm: sha1'))
3193
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003194 def test_export_md5_digest(self):
3195 """
3196 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3197 not emit a deprecation warning.
3198 """
3199 crl = self._get_crl()
3200 with catch_warnings(record=True) as catcher:
3201 simplefilter("always")
3202 self.assertEqual(0, len(catcher))
3203 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3204 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3205 text.index(b('Signature Algorithm: md5'))
3206
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003207 def test_export_default_digest(self):
3208 """
3209 If not passed the name of a digest function, ``CRL.export`` uses a
3210 signature algorithm based on MD5 and emits a deprecation warning.
3211 """
3212 crl = self._get_crl()
3213 with catch_warnings(record=True) as catcher:
3214 simplefilter("always")
3215 dumped_crl = crl.export(self.cert, self.pkey)
3216 self.assertEqual(
3217 "The default message digest (md5) is deprecated. "
3218 "Pass the name of a message digest explicitly.",
3219 str(catcher[0].message),
3220 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003221 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3222 text.index(b('Signature Algorithm: md5'))
3223
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003224 def test_export_invalid(self):
3225 """
3226 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003227 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003228 """
3229 crl = CRL()
3230 self.assertRaises(Error, crl.export, X509(), PKey())
3231
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003232 def test_add_revoked_keyword(self):
3233 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003234 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003235 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003236 """
3237 crl = CRL()
3238 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003239 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003240 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003241 crl.add_revoked(revoked=revoked)
3242 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3243
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003244 def test_export_wrong_args(self):
3245 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003246 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003247 four arguments, or with arguments other than the certificate,
3248 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003249 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003250 """
3251 crl = CRL()
3252 self.assertRaises(TypeError, crl.export)
3253 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003254 with pytest.raises(TypeError):
3255 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3256 with pytest.raises(TypeError):
3257 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3258 with pytest.raises(TypeError):
3259 crl.export(self.cert, None, FILETYPE_PEM, 10)
3260 with pytest.raises(TypeError):
3261 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003262 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3263
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003264 def test_export_unknown_filetype(self):
3265 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003266 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003267 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3268 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003269 """
3270 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003271 with pytest.raises(ValueError):
3272 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003273
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003274 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003275 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003276 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003277 in a :py:obj:`ValueError` being raised.
3278 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003279 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003280 self.assertRaises(
3281 ValueError,
3282 crl.export,
3283 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3284 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003285
Rick Dean536ba022009-07-24 23:57:27 -05003286 def test_get_revoked(self):
3287 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003288 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003289 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3290 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003291 """
3292 crl = CRL()
3293
3294 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003295 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003296 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003297 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003298 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003299 revoked.set_serial(b('100'))
3300 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003301 crl.add_revoked(revoked)
3302
3303 revs = crl.get_revoked()
3304 self.assertEqual(len(revs), 2)
3305 self.assertEqual(type(revs[0]), Revoked)
3306 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003307 self.assertEqual(revs[0].get_serial(), b('03AB'))
3308 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003309 self.assertEqual(revs[0].get_rev_date(), now)
3310 self.assertEqual(revs[1].get_rev_date(), now)
3311
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003312 def test_get_revoked_wrong_args(self):
3313 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003314 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3315 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003316 """
3317 crl = CRL()
3318 self.assertRaises(TypeError, crl.get_revoked, None)
3319 self.assertRaises(TypeError, crl.get_revoked, 1)
3320 self.assertRaises(TypeError, crl.get_revoked, "")
3321 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3322
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003323 def test_add_revoked_wrong_args(self):
3324 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003325 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3326 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003327 """
3328 crl = CRL()
3329 self.assertRaises(TypeError, crl.add_revoked)
3330 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3331 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3332
Rick Dean536ba022009-07-24 23:57:27 -05003333 def test_load_crl(self):
3334 """
3335 Load a known CRL and inspect its revocations. Both
3336 PEM and DER formats are loaded.
3337 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003338 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003339 revs = crl.get_revoked()
3340 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003341 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003342 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003343 self.assertEqual(revs[1].get_serial(), b('0100'))
3344 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003345
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003346 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003347 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003348 revs = crl.get_revoked()
3349 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003350 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003351 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003352 self.assertEqual(revs[1].get_serial(), b('0100'))
3353 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003354
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003355 def test_load_crl_wrong_args(self):
3356 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003357 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3358 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003359 """
3360 self.assertRaises(TypeError, load_crl)
3361 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3362 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3363
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003364 def test_load_crl_bad_filetype(self):
3365 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003366 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3367 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003368 """
3369 self.assertRaises(ValueError, load_crl, 100, crlData)
3370
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003371 def test_load_crl_bad_data(self):
3372 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003373 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3374 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003375 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003376 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003377
Dominic Chenf05b2122015-10-13 16:32:35 +00003378 def test_dump_crl(self):
3379 """
3380 The dumped CRL matches the original input.
3381 """
3382 crl = load_crl(FILETYPE_PEM, crlData)
3383 buf = dump_crl(FILETYPE_PEM, crl)
3384 assert buf == crlData
3385
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003386
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003387class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003388 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003389 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003390 """
3391 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3392 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003393 intermediate_server_cert = load_certificate(
3394 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003395
3396 def test_valid(self):
3397 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003398 :py:obj:`verify_certificate` returns ``None`` when called with a
3399 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003400 """
3401 store = X509Store()
3402 store.add_cert(self.root_cert)
3403 store.add_cert(self.intermediate_cert)
3404 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003405 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003406
3407 def test_reuse(self):
3408 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003409 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003410 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003411 """
3412 store = X509Store()
3413 store.add_cert(self.root_cert)
3414 store.add_cert(self.intermediate_cert)
3415 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003416 self.assertEqual(store_ctx.verify_certificate(), None)
3417 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003418
3419 def test_trusted_self_signed(self):
3420 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003421 :py:obj:`verify_certificate` returns ``None`` when called with a
3422 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003423 """
3424 store = X509Store()
3425 store.add_cert(self.root_cert)
3426 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003427 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003428
3429 def test_untrusted_self_signed(self):
3430 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003431 :py:obj:`verify_certificate` raises error when a self-signed
3432 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003433 """
3434 store = X509Store()
3435 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003436 with pytest.raises(X509StoreContextError) as exc:
3437 store_ctx.verify_certificate()
3438
3439 assert exc.value.args[0][2] == 'self signed certificate'
3440 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003441
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003442 def test_invalid_chain_no_root(self):
3443 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003444 :py:obj:`verify_certificate` raises error when a root certificate is
3445 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003446 """
3447 store = X509Store()
3448 store.add_cert(self.intermediate_cert)
3449 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003450
3451 with pytest.raises(X509StoreContextError) as exc:
3452 store_ctx.verify_certificate()
3453
3454 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3455 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003456
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003457 def test_invalid_chain_no_intermediate(self):
3458 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003459 :py:obj:`verify_certificate` raises error when an intermediate
3460 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003461 """
3462 store = X509Store()
3463 store.add_cert(self.root_cert)
3464 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003465
Alex Gaynor85b49702015-09-05 16:30:59 -04003466 with pytest.raises(X509StoreContextError) as exc:
3467 store_ctx.verify_certificate()
3468
3469 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3470 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003471
Stephen Holsapple46a09252015-02-12 14:45:43 -08003472 def test_modification_pre_verify(self):
3473 """
3474 :py:obj:`verify_certificate` can use a store context modified after
3475 instantiation.
3476 """
3477 store_bad = X509Store()
3478 store_bad.add_cert(self.intermediate_cert)
3479 store_good = X509Store()
3480 store_good.add_cert(self.root_cert)
3481 store_good.add_cert(self.intermediate_cert)
3482 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003483
3484 with pytest.raises(X509StoreContextError) as exc:
3485 store_ctx.verify_certificate()
3486
3487 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3488 assert exc.value.certificate.get_subject().CN == 'intermediate'
3489
Stephen Holsapple46a09252015-02-12 14:45:43 -08003490 store_ctx.set_store(store_good)
3491 self.assertEqual(store_ctx.verify_certificate(), None)
3492
3493
James Yonan7c2e5d32010-02-27 05:45:50 -07003494class SignVerifyTests(TestCase):
3495 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003496 Tests for :py:obj:`OpenSSL.crypto.sign` and
3497 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003498 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003499
James Yonan7c2e5d32010-02-27 05:45:50 -07003500 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003501 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003502 :py:obj:`sign` generates a cryptographic signature which
3503 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003504 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003505 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003506 "It was a bright cold day in April, and the clocks were striking "
3507 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3508 "effort to escape the vile wind, slipped quickly through the "
3509 "glass doors of Victory Mansions, though not quickly enough to "
3510 "prevent a swirl of gritty dust from entering along with him.")
3511
3512 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003513 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003514 # verify the content with this cert
3515 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3516 # certificate unrelated to priv_key, used to trigger an error
3517 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003518
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003519 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003520 sig = sign(priv_key, content, digest)
3521
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003522 # Verify the signature of content, will throw an exception if
3523 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003524 verify(good_cert, sig, content, digest)
3525
3526 # This should fail because the certificate doesn't match the
3527 # private key that was used to sign the content.
3528 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3529
3530 # This should fail because we've "tainted" the content after
3531 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003532 self.assertRaises(
3533 Error, verify,
3534 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003535
3536 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003537 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003538 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003539 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003540 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003541
Abraham Martinc5484ba2015-03-25 15:33:05 +00003542 def test_sign_verify_with_text(self):
3543 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003544 :py:obj:`sign` generates a cryptographic signature which
3545 :py:obj:`verify` can check. Deprecation warnings raised because using
3546 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003547 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003548 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003549 b"It was a bright cold day in April, and the clocks were striking "
3550 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3551 b"effort to escape the vile wind, slipped quickly through the "
3552 b"glass doors of Victory Mansions, though not quickly enough to "
3553 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003554 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003555
3556 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3557 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3558 for digest in ['md5', 'sha1']:
3559 with catch_warnings(record=True) as w:
3560 simplefilter("always")
3561 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003562
3563 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003564 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003565 WARNING_TYPE_EXPECTED
3566 ),
3567 str(w[-1].message)
3568 )
3569 self.assertIs(w[-1].category, DeprecationWarning)
3570
Abraham Martinc5484ba2015-03-25 15:33:05 +00003571 with catch_warnings(record=True) as w:
3572 simplefilter("always")
3573 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003574
3575 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003576 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003577 WARNING_TYPE_EXPECTED
3578 ),
3579 str(w[-1].message)
3580 )
3581 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003582
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003583 def test_sign_nulls(self):
3584 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003585 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003586 """
3587 content = b("Watch out! \0 Did you see it?")
3588 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3589 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3590 sig = sign(priv_key, content, "sha1")
3591 verify(good_cert, sig, content, "sha1")
3592
Colleen Murphye09399b2016-03-01 17:40:49 -08003593 def test_sign_with_large_key(self):
3594 """
3595 :py:obj:`sign` produces a signature for a string when using a long key.
3596 """
3597 content = b(
3598 "It was a bright cold day in April, and the clocks were striking "
3599 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3600 "effort to escape the vile wind, slipped quickly through the "
3601 "glass doors of Victory Mansions, though not quickly enough to "
3602 "prevent a swirl of gritty dust from entering along with him.")
3603
3604 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3605 sign(priv_key, content, "sha1")
3606
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003607
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003608class EllipticCurveTests(TestCase):
3609 """
3610 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3611 :py:obj:`get_elliptic_curves`.
3612 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003613
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003614 def test_set(self):
3615 """
3616 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3617 """
3618 self.assertIsInstance(get_elliptic_curves(), set)
3619
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003620 def test_some_curves(self):
3621 """
3622 If :py:mod:`cryptography` has elliptic curve support then the set
3623 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3624 it.
3625
3626 There could be an OpenSSL that violates this assumption. If so, this
3627 test will fail and we'll find out.
3628 """
3629 curves = get_elliptic_curves()
3630 if lib.Cryptography_HAS_EC:
3631 self.assertTrue(curves)
3632 else:
3633 self.assertFalse(curves)
3634
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003635 def test_a_curve(self):
3636 """
3637 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3638 supported curve.
3639 """
3640 curves = get_elliptic_curves()
3641 if curves:
3642 curve = next(iter(curves))
3643 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3644 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003645 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003646
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003647 def test_not_a_curve(self):
3648 """
3649 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3650 with a name which does not identify a supported curve.
3651 """
3652 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003653 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003654
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003655 def test_repr(self):
3656 """
3657 The string representation of a curve object includes simply states the
3658 object is a curve and what its name is.
3659 """
3660 curves = get_elliptic_curves()
3661 if curves:
3662 curve = next(iter(curves))
3663 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3664
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003665 def test_to_EC_KEY(self):
3666 """
3667 The curve object can export a version of itself as an EC_KEY* via the
3668 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3669 """
3670 curves = get_elliptic_curves()
3671 if curves:
3672 curve = next(iter(curves))
3673 # It's not easy to assert anything about this object. However, see
3674 # leakcheck/crypto.py for a test that demonstrates it at least does
3675 # not leak memory.
3676 curve._to_EC_KEY()
3677
3678
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003679class EllipticCurveFactory(object):
3680 """
3681 A helper to get the names of two curves.
3682 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003683
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003684 def __init__(self):
3685 curves = iter(get_elliptic_curves())
3686 try:
3687 self.curve_name = next(curves).name
3688 self.another_curve_name = next(curves).name
3689 except StopIteration:
3690 self.curve_name = self.another_curve_name = None
3691
3692
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003693class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3694 """
3695 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3696 """
3697 curve_factory = EllipticCurveFactory()
3698
3699 if curve_factory.curve_name is None:
3700 skip = "There are no curves available there can be no curve objects."
3701
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003702 def anInstance(self):
3703 """
3704 Get the curve object for an arbitrary curve supported by the system.
3705 """
3706 return get_elliptic_curve(self.curve_factory.curve_name)
3707
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003708 def anotherInstance(self):
3709 """
3710 Get the curve object for an arbitrary curve supported by the system -
3711 but not the one returned by C{anInstance}.
3712 """
3713 return get_elliptic_curve(self.curve_factory.another_curve_name)
3714
3715
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003716class EllipticCurveHashTests(TestCase):
3717 """
3718 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3719 as an item in a :py:type:`dict` or :py:type:`set`).
3720 """
3721 curve_factory = EllipticCurveFactory()
3722
3723 if curve_factory.curve_name is None:
3724 skip = "There are no curves available there can be no curve objects."
3725
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003726 def test_contains(self):
3727 """
3728 The ``in`` operator reports that a :py:type:`set` containing a curve
3729 does contain that curve.
3730 """
3731 curve = get_elliptic_curve(self.curve_factory.curve_name)
3732 curves = set([curve])
3733 self.assertIn(curve, curves)
3734
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003735 def test_does_not_contain(self):
3736 """
3737 The ``in`` operator reports that a :py:type:`set` not containing a
3738 curve does not contain that curve.
3739 """
3740 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003741 curves = set([
3742 get_elliptic_curve(self.curve_factory.another_curve_name)
3743 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003744 self.assertNotIn(curve, curves)
3745
3746
Rick Dean5b7b6372009-04-01 11:34:06 -05003747if __name__ == '__main__':
3748 main()