blob: eeea306697b30e659938e2cea9a229625ae13056 [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
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002430class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002431 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002432 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002433 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002434 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002435 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002436 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002437 """
2438 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002439
2440 assert True is key._only_public
2441 assert 2048 == key.bits()
2442 assert TYPE_RSA == key.type()
2443
2444 def test_invalid_type(self):
2445 """
2446 load_publickey doesn't support FILETYPE_TEXT.
2447 """
2448 with pytest.raises(ValueError):
2449 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2450
2451 def test_invalid_key_format(self):
2452 """
2453 load_publickey explodes on incorrect keys.
2454 """
2455 with pytest.raises(Error):
2456 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2457
2458 def test_tolerates_unicode_strings(self):
2459 """
2460 load_publickey works with text strings, not just bytes.
2461 """
2462 serialized = cleartextPublicKeyPEM.decode('ascii')
2463 key = load_publickey(FILETYPE_PEM, serialized)
2464 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2465
2466 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002467
2468
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002469class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002470 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002471 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002472
2473 Add new tests to `TestFunctions` above.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002474 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002475
2476 def test_load_privatekey_invalid_format(self):
2477 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002478 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2479 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002480 """
2481 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2482
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002483 def test_load_privatekey_invalid_passphrase_type(self):
2484 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002485 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2486 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002487 """
2488 self.assertRaises(
2489 TypeError,
2490 load_privatekey,
2491 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2492
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002493 def test_load_privatekey_wrong_args(self):
2494 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002495 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2496 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002497 """
2498 self.assertRaises(TypeError, load_privatekey)
2499
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002500 def test_load_privatekey_wrongPassphrase(self):
2501 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002502 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2503 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002504 """
2505 self.assertRaises(
2506 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002507 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002508
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002509 def test_load_privatekey_passphraseWrongType(self):
2510 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002511 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2512 a passphrase with a private key encoded in a format, that doesn't
2513 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002514 """
2515 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2516 blob = dump_privatekey(FILETYPE_ASN1, key)
2517 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002518 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002519
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002520 def test_load_privatekey_passphrase(self):
2521 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002522 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2523 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002524 """
2525 key = load_privatekey(
2526 FILETYPE_PEM, encryptedPrivateKeyPEM,
2527 encryptedPrivateKeyPEMPassphrase)
2528 self.assertTrue(isinstance(key, PKeyType))
2529
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002530 def test_load_privatekey_passphrase_exception(self):
2531 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002532 If the passphrase callback raises an exception, that exception is
2533 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002534 """
2535 def cb(ignored):
2536 raise ArithmeticError
2537
Alex Gaynor791212d2015-09-05 15:46:08 -04002538 with pytest.raises(ArithmeticError):
2539 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002540
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002541 def test_load_privatekey_wrongPassphraseCallback(self):
2542 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002543 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2544 is passed an encrypted PEM and a passphrase callback which returns an
2545 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002546 """
2547 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002548
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002549 def cb(*a):
2550 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002551 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002552 self.assertRaises(
2553 Error,
2554 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2555 self.assertTrue(called)
2556
2557 def test_load_privatekey_passphraseCallback(self):
2558 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002559 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2560 encrypted PEM string if given a passphrase callback which returns the
2561 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002562 """
2563 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002564
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002565 def cb(writing):
2566 called.append(writing)
2567 return encryptedPrivateKeyPEMPassphrase
2568 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2569 self.assertTrue(isinstance(key, PKeyType))
2570 self.assertEqual(called, [False])
2571
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002572 def test_load_privatekey_passphrase_wrong_return_type(self):
2573 """
2574 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2575 callback returns something other than a byte string.
2576 """
2577 self.assertRaises(
2578 ValueError,
2579 load_privatekey,
2580 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2581
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002582 def test_dump_privatekey_wrong_args(self):
2583 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002584 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2585 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002586 """
2587 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002588 # If cipher name is given, password is required.
2589 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002590 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002591
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002592 def test_dump_privatekey_unknown_cipher(self):
2593 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002594 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2595 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002596 """
2597 key = PKey()
2598 key.generate_key(TYPE_RSA, 512)
2599 self.assertRaises(
2600 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002601 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002602
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002603 def test_dump_privatekey_invalid_passphrase_type(self):
2604 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002605 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2606 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002607 """
2608 key = PKey()
2609 key.generate_key(TYPE_RSA, 512)
2610 self.assertRaises(
2611 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002612 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002613
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002614 def test_dump_privatekey_invalid_filetype(self):
2615 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002616 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2617 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002618 """
2619 key = PKey()
2620 key.generate_key(TYPE_RSA, 512)
2621 self.assertRaises(ValueError, dump_privatekey, 100, key)
2622
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002623 def test_load_privatekey_passphraseCallbackLength(self):
2624 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002625 :py:obj:`crypto.load_privatekey` should raise an error when the
2626 passphrase provided by the callback is too long, not silently truncate
2627 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002628 """
2629 def cb(ignored):
2630 return "a" * 1025
2631
Alex Gaynor791212d2015-09-05 15:46:08 -04002632 with pytest.raises(ValueError):
2633 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002634
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002635 def test_dump_privatekey_passphrase(self):
2636 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002637 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2638 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002639 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002640 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002641 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002642 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2643 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002644 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2645 self.assertTrue(isinstance(loadedKey, PKeyType))
2646 self.assertEqual(loadedKey.type(), key.type())
2647 self.assertEqual(loadedKey.bits(), key.bits())
2648
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002649 def test_dump_privatekey_passphraseWrongType(self):
2650 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002651 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2652 a passphrase with a private key encoded in a format, that doesn't
2653 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002654 """
2655 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002656 with pytest.raises(ValueError):
2657 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002658
Rick Dean5b7b6372009-04-01 11:34:06 -05002659 def test_dump_certificate(self):
2660 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002661 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002662 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002663 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002664 cert = load_certificate(FILETYPE_PEM, pemData)
2665 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2666 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2667 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002668 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002669 self.assertEqual(dumped_der, good_der)
2670 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2671 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2672 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2673 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002674 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002675 self.assertEqual(dumped_text, good_text)
2676
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002677 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002678 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002679 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002680 """
2681 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002682 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002683 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2684 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002685
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002686 def test_dump_privatekey_asn1(self):
2687 """
2688 :py:obj:`dump_privatekey` writes a DER
2689 """
2690 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2691 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2692
Rick Dean5b7b6372009-04-01 11:34:06 -05002693 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002694 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002695 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002696 self.assertEqual(dumped_der, good_der)
2697 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2698 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2699 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002700
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002701 def test_dump_privatekey_text(self):
2702 """
2703 :py:obj:`dump_privatekey` writes a text
2704 """
2705 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2706 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2707
Rick Dean5b7b6372009-04-01 11:34:06 -05002708 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002709 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002710 self.assertEqual(dumped_text, good_text)
2711
Cory Benfield6492f7c2015-10-27 16:57:58 +09002712 def test_dump_publickey_pem(self):
2713 """
Cory Benfield11c10192015-10-27 17:23:03 +09002714 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002715 """
2716 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2717 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002718 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002719
2720 def test_dump_publickey_asn1(self):
2721 """
Cory Benfield11c10192015-10-27 17:23:03 +09002722 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002723 """
2724 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2725 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2726 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2727 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002728 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002729
Cory Benfielde02c7d82015-10-27 17:34:49 +09002730 def test_dump_publickey_invalid_type(self):
2731 """
2732 dump_publickey doesn't support FILETYPE_TEXT.
2733 """
2734 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2735
2736 with pytest.raises(ValueError):
2737 dump_publickey(FILETYPE_TEXT, key)
2738
Rick Dean5b7b6372009-04-01 11:34:06 -05002739 def test_dump_certificate_request(self):
2740 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002741 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002742 """
Alex Gaynor31287502015-09-05 16:11:27 -04002743 req = load_certificate_request(
2744 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002745 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2746 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2747 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002748 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002749 self.assertEqual(dumped_der, good_der)
2750 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2751 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2752 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2753 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002754 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002755 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002756 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002757
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002758 def test_dump_privatekey_passphraseCallback(self):
2759 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002760 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2761 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002762 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002763 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002764 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002765
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002766 def cb(writing):
2767 called.append(writing)
2768 return passphrase
2769 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002770 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2771 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002772 self.assertEqual(called, [True])
2773 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2774 self.assertTrue(isinstance(loadedKey, PKeyType))
2775 self.assertEqual(loadedKey.type(), key.type())
2776 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002777
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002778 def test_dump_privatekey_passphrase_exception(self):
2779 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002780 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002781 by the passphrase callback.
2782 """
2783 def cb(ignored):
2784 raise ArithmeticError
2785
2786 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002787 with pytest.raises(ArithmeticError):
2788 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002789
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002790 def test_dump_privatekey_passphraseCallbackLength(self):
2791 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002792 :py:obj:`crypto.dump_privatekey` should raise an error when the
2793 passphrase provided by the callback is too long, not silently truncate
2794 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002795 """
2796 def cb(ignored):
2797 return "a" * 1025
2798
2799 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002800 with pytest.raises(ValueError):
2801 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002802
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002803 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002804 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002805 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2806 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002807 """
2808 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2809 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2810
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002811 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002812 """
2813 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2814 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2815 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002816 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2817 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2818
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002819 def test_load_pkcs7_data_invalid(self):
2820 """
2821 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2822 :py:obj:`Error` is raised.
2823 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002824 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002825
2826
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002827class LoadCertificateTests(TestCase):
2828 """
2829 Tests for :py:obj:`load_certificate_request`.
2830 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002831
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002832 def test_badFileType(self):
2833 """
2834 If the file type passed to :py:obj:`load_certificate_request` is
2835 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2836 :py:class:`ValueError` is raised.
2837 """
2838 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2839
2840
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002841class PKCS7Tests(TestCase):
2842 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002843 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002844 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002845
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002846 def test_type(self):
2847 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002848 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002849 """
2850 self.assertTrue(isinstance(PKCS7Type, type))
2851 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2852
2853 # XXX This doesn't currently work.
2854 # self.assertIdentical(PKCS7, PKCS7Type)
2855
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002856 # XXX Opposite results for all these following methods
2857
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002858 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002859 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002860 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2861 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002862 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002863 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2864 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2865
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002866 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002867 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002868 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2869 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002870 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002871 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2872 self.assertTrue(pkcs7.type_is_signed())
2873
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002874 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002875 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002876 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2877 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002878 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002879 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2880 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2881
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002882 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002883 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002884 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2885 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002886 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002887 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2888 self.assertFalse(pkcs7.type_is_enveloped())
2889
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002890 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002891 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002892 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2893 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002894 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002895 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2896 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2897
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002898 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002899 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002900 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2901 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002902 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002903 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2904 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2905
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002906 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002907 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002908 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2909 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002910 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002911 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2912 self.assertFalse(pkcs7.type_is_data())
2913
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002914 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002915 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002916 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2917 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002918 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002919 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2920 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2921
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002922 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002923 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002924 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2925 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002926 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002927 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2928 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2929
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002930 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002931 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002932 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2933 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002934 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002935 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002936 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002937
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002938 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002939 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002940 If an attribute other than one of the methods tested here is accessed
2941 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2942 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002943 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002944 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2945 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2946
2947
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002948class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002949 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002950 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002951 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002952
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002953 def signable(self):
2954 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002955 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002956 """
2957 return NetscapeSPKI()
2958
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002959 def test_type(self):
2960 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002961 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2962 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002963 """
2964 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2965 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2966
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002967 def test_construction(self):
2968 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002969 :py:obj:`NetscapeSPKI` returns an instance of
2970 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002971 """
2972 nspki = NetscapeSPKI()
2973 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2974
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002975 def test_invalid_attribute(self):
2976 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002977 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2978 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002979 """
2980 nspki = NetscapeSPKI()
2981 self.assertRaises(AttributeError, lambda: nspki.foo)
2982
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002983 def test_b64_encode(self):
2984 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002985 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2986 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002987 """
2988 nspki = NetscapeSPKI()
2989 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002990 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002991
2992
Paul Kehrer2c605ba2016-03-11 11:17:26 -04002993class TestRevoked(object):
2994 """
2995 Please add test cases for the Revoked class here if possible. This class
2996 holds the new py.test style tests.
2997 """
2998 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
2999 """
3000 The get_reason method on the Revoked class checks to see if the
3001 extension is NID_crl_reason and should skip it otherwise. This test
3002 loads a CRL with extensions it should ignore.
3003 """
3004 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3005 revoked = crl.get_revoked()
3006 reason = revoked[1].get_reason()
3007 assert reason == b'Unspecified'
3008
3009 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3010 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3011 revoked = crl.get_revoked()
3012 revoked[1].set_reason(None)
3013 reason = revoked[1].get_reason()
3014 assert reason is None
3015
3016
Rick Dean536ba022009-07-24 23:57:27 -05003017class RevokedTests(TestCase):
3018 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003019 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3020 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003021 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003022
Rick Dean536ba022009-07-24 23:57:27 -05003023 def test_construction(self):
3024 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003025 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003026 that it is empty.
3027 """
3028 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003029 self.assertTrue(isinstance(revoked, Revoked))
3030 self.assertEquals(type(revoked), Revoked)
3031 self.assertEquals(revoked.get_serial(), b('00'))
3032 self.assertEquals(revoked.get_rev_date(), None)
3033 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003034
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003035 def test_construction_wrong_args(self):
3036 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003037 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3038 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003039 """
3040 self.assertRaises(TypeError, Revoked, None)
3041 self.assertRaises(TypeError, Revoked, 1)
3042 self.assertRaises(TypeError, Revoked, "foo")
3043
Rick Dean536ba022009-07-24 23:57:27 -05003044 def test_serial(self):
3045 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003046 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003047 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003048 with grace.
3049 """
3050 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003051 ret = revoked.set_serial(b('10b'))
3052 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003053 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003054 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003055
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003056 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003057 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003058 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003059
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003060 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003061 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003062 self.assertRaises(TypeError, revoked.get_serial, 1)
3063 self.assertRaises(TypeError, revoked.get_serial, None)
3064 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003065
Rick Dean536ba022009-07-24 23:57:27 -05003066 def test_date(self):
3067 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003068 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003069 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003070 with grace.
3071 """
3072 revoked = Revoked()
3073 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003074 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003075
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003076 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003077 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003078 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003079 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003080 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003081
Rick Dean6385faf2009-07-26 00:07:47 -05003082 def test_reason(self):
3083 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003084 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003085 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003086 as "set". Likewise, each reason of all_reasons() must work.
3087 """
3088 revoked = Revoked()
3089 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003090 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003091 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003092 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003093 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003094 self.assertEquals(
3095 reason.lower().replace(b(' '), b('')),
3096 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003097 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003098
3099 revoked.set_reason(None)
3100 self.assertEqual(revoked.get_reason(), None)
3101
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003102 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003103 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003104 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003105 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003106 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003107 """
3108 revoked = Revoked()
3109 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003110 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003111
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003112 def test_get_reason_wrong_arguments(self):
3113 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003114 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3115 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003116 """
3117 revoked = Revoked()
3118 self.assertRaises(TypeError, revoked.get_reason, None)
3119 self.assertRaises(TypeError, revoked.get_reason, 1)
3120 self.assertRaises(TypeError, revoked.get_reason, "foo")
3121
3122
Rick Dean536ba022009-07-24 23:57:27 -05003123class CRLTests(TestCase):
3124 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003125 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003126 """
3127 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3128 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3129
3130 def test_construction(self):
3131 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003132 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003133 that it is empty
3134 """
3135 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003136 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003137 self.assertEqual(crl.get_revoked(), None)
3138
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003139 def test_construction_wrong_args(self):
3140 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003141 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3142 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003143 """
3144 self.assertRaises(TypeError, CRL, 1)
3145 self.assertRaises(TypeError, CRL, "")
3146 self.assertRaises(TypeError, CRL, None)
3147
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003148 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003149 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003150 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003151 """
3152 crl = CRL()
3153 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003154 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003155 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003156 revoked.set_serial(b('3ab'))
3157 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003158 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003159 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003160
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003161 def test_export_pem(self):
3162 """
3163 If not passed a format, ``CRL.export`` returns a "PEM" format string
3164 representing a serial number, a revoked reason, and certificate issuer
3165 information.
3166 """
3167 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003168 # PEM format
3169 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003170 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003171
3172 # These magic values are based on the way the CRL above was constructed
3173 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003174 text.index(b('Serial Number: 03AB'))
3175 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003176 text.index(
3177 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3178 )
3179
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003180 def test_export_der(self):
3181 """
3182 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3183 "DER" format string representing a serial number, a revoked reason, and
3184 certificate issuer information.
3185 """
3186 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003187
3188 # DER format
3189 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003190 text = _runopenssl(
3191 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3192 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003193 text.index(b('Serial Number: 03AB'))
3194 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003195 text.index(
3196 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3197 )
3198
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003199 def test_export_text(self):
3200 """
3201 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3202 text format string like the one produced by the openssl command line
3203 tool.
3204 """
3205 crl = self._get_crl()
3206
3207 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3208 text = _runopenssl(
3209 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3210 )
Rick Dean536ba022009-07-24 23:57:27 -05003211
3212 # text format
3213 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3214 self.assertEqual(text, dumped_text)
3215
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003216 def test_export_custom_digest(self):
3217 """
3218 If passed the name of a digest function, ``CRL.export`` uses a
3219 signature algorithm based on that digest function.
3220 """
3221 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003222 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003223 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3224 text.index(b('Signature Algorithm: sha1'))
3225
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003226 def test_export_md5_digest(self):
3227 """
3228 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3229 not emit a deprecation warning.
3230 """
3231 crl = self._get_crl()
3232 with catch_warnings(record=True) as catcher:
3233 simplefilter("always")
3234 self.assertEqual(0, len(catcher))
3235 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3236 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3237 text.index(b('Signature Algorithm: md5'))
3238
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003239 def test_export_default_digest(self):
3240 """
3241 If not passed the name of a digest function, ``CRL.export`` uses a
3242 signature algorithm based on MD5 and emits a deprecation warning.
3243 """
3244 crl = self._get_crl()
3245 with catch_warnings(record=True) as catcher:
3246 simplefilter("always")
3247 dumped_crl = crl.export(self.cert, self.pkey)
3248 self.assertEqual(
3249 "The default message digest (md5) is deprecated. "
3250 "Pass the name of a message digest explicitly.",
3251 str(catcher[0].message),
3252 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003253 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3254 text.index(b('Signature Algorithm: md5'))
3255
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003256 def test_export_invalid(self):
3257 """
3258 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003259 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003260 """
3261 crl = CRL()
3262 self.assertRaises(Error, crl.export, X509(), PKey())
3263
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003264 def test_add_revoked_keyword(self):
3265 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003266 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003267 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003268 """
3269 crl = CRL()
3270 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003271 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003272 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003273 crl.add_revoked(revoked=revoked)
3274 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3275
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003276 def test_export_wrong_args(self):
3277 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003278 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003279 four arguments, or with arguments other than the certificate,
3280 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003281 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003282 """
3283 crl = CRL()
3284 self.assertRaises(TypeError, crl.export)
3285 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003286 with pytest.raises(TypeError):
3287 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3288 with pytest.raises(TypeError):
3289 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3290 with pytest.raises(TypeError):
3291 crl.export(self.cert, None, FILETYPE_PEM, 10)
3292 with pytest.raises(TypeError):
3293 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003294 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3295
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003296 def test_export_unknown_filetype(self):
3297 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003298 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003299 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3300 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003301 """
3302 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003303 with pytest.raises(ValueError):
3304 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003305
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003306 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003307 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003308 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003309 in a :py:obj:`ValueError` being raised.
3310 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003311 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003312 self.assertRaises(
3313 ValueError,
3314 crl.export,
3315 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3316 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003317
Rick Dean536ba022009-07-24 23:57:27 -05003318 def test_get_revoked(self):
3319 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003320 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003321 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3322 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003323 """
3324 crl = CRL()
3325
3326 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003327 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003328 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003329 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003330 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003331 revoked.set_serial(b('100'))
3332 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003333 crl.add_revoked(revoked)
3334
3335 revs = crl.get_revoked()
3336 self.assertEqual(len(revs), 2)
3337 self.assertEqual(type(revs[0]), Revoked)
3338 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003339 self.assertEqual(revs[0].get_serial(), b('03AB'))
3340 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003341 self.assertEqual(revs[0].get_rev_date(), now)
3342 self.assertEqual(revs[1].get_rev_date(), now)
3343
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003344 def test_get_revoked_wrong_args(self):
3345 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003346 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3347 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003348 """
3349 crl = CRL()
3350 self.assertRaises(TypeError, crl.get_revoked, None)
3351 self.assertRaises(TypeError, crl.get_revoked, 1)
3352 self.assertRaises(TypeError, crl.get_revoked, "")
3353 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3354
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003355 def test_add_revoked_wrong_args(self):
3356 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003357 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3358 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003359 """
3360 crl = CRL()
3361 self.assertRaises(TypeError, crl.add_revoked)
3362 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3363 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3364
Rick Dean536ba022009-07-24 23:57:27 -05003365 def test_load_crl(self):
3366 """
3367 Load a known CRL and inspect its revocations. Both
3368 PEM and DER formats are loaded.
3369 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003370 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003371 revs = crl.get_revoked()
3372 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003373 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003374 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003375 self.assertEqual(revs[1].get_serial(), b('0100'))
3376 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003377
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003378 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003379 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003380 revs = crl.get_revoked()
3381 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003382 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003383 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003384 self.assertEqual(revs[1].get_serial(), b('0100'))
3385 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003386
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003387 def test_load_crl_wrong_args(self):
3388 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003389 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3390 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003391 """
3392 self.assertRaises(TypeError, load_crl)
3393 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3394 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3395
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003396 def test_load_crl_bad_filetype(self):
3397 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003398 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3399 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003400 """
3401 self.assertRaises(ValueError, load_crl, 100, crlData)
3402
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003403 def test_load_crl_bad_data(self):
3404 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003405 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3406 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003407 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003408 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003409
Dominic Chenf05b2122015-10-13 16:32:35 +00003410 def test_dump_crl(self):
3411 """
3412 The dumped CRL matches the original input.
3413 """
3414 crl = load_crl(FILETYPE_PEM, crlData)
3415 buf = dump_crl(FILETYPE_PEM, crl)
3416 assert buf == crlData
3417
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003418
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003419class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003420 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003421 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003422 """
3423 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3424 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003425 intermediate_server_cert = load_certificate(
3426 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003427
3428 def test_valid(self):
3429 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003430 :py:obj:`verify_certificate` returns ``None`` when called with a
3431 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003432 """
3433 store = X509Store()
3434 store.add_cert(self.root_cert)
3435 store.add_cert(self.intermediate_cert)
3436 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003437 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003438
3439 def test_reuse(self):
3440 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003441 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003442 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003443 """
3444 store = X509Store()
3445 store.add_cert(self.root_cert)
3446 store.add_cert(self.intermediate_cert)
3447 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003448 self.assertEqual(store_ctx.verify_certificate(), None)
3449 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003450
3451 def test_trusted_self_signed(self):
3452 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003453 :py:obj:`verify_certificate` returns ``None`` when called with a
3454 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003455 """
3456 store = X509Store()
3457 store.add_cert(self.root_cert)
3458 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003459 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003460
3461 def test_untrusted_self_signed(self):
3462 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003463 :py:obj:`verify_certificate` raises error when a self-signed
3464 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003465 """
3466 store = X509Store()
3467 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003468 with pytest.raises(X509StoreContextError) as exc:
3469 store_ctx.verify_certificate()
3470
3471 assert exc.value.args[0][2] == 'self signed certificate'
3472 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003473
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003474 def test_invalid_chain_no_root(self):
3475 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003476 :py:obj:`verify_certificate` raises error when a root certificate is
3477 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003478 """
3479 store = X509Store()
3480 store.add_cert(self.intermediate_cert)
3481 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003482
3483 with pytest.raises(X509StoreContextError) as exc:
3484 store_ctx.verify_certificate()
3485
3486 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3487 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003488
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003489 def test_invalid_chain_no_intermediate(self):
3490 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003491 :py:obj:`verify_certificate` raises error when an intermediate
3492 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003493 """
3494 store = X509Store()
3495 store.add_cert(self.root_cert)
3496 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003497
Alex Gaynor85b49702015-09-05 16:30:59 -04003498 with pytest.raises(X509StoreContextError) as exc:
3499 store_ctx.verify_certificate()
3500
3501 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3502 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003503
Stephen Holsapple46a09252015-02-12 14:45:43 -08003504 def test_modification_pre_verify(self):
3505 """
3506 :py:obj:`verify_certificate` can use a store context modified after
3507 instantiation.
3508 """
3509 store_bad = X509Store()
3510 store_bad.add_cert(self.intermediate_cert)
3511 store_good = X509Store()
3512 store_good.add_cert(self.root_cert)
3513 store_good.add_cert(self.intermediate_cert)
3514 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003515
3516 with pytest.raises(X509StoreContextError) as exc:
3517 store_ctx.verify_certificate()
3518
3519 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3520 assert exc.value.certificate.get_subject().CN == 'intermediate'
3521
Stephen Holsapple46a09252015-02-12 14:45:43 -08003522 store_ctx.set_store(store_good)
3523 self.assertEqual(store_ctx.verify_certificate(), None)
3524
3525
James Yonan7c2e5d32010-02-27 05:45:50 -07003526class SignVerifyTests(TestCase):
3527 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003528 Tests for :py:obj:`OpenSSL.crypto.sign` and
3529 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003530 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003531
James Yonan7c2e5d32010-02-27 05:45:50 -07003532 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003533 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003534 :py:obj:`sign` generates a cryptographic signature which
3535 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003536 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003537 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003538 "It was a bright cold day in April, and the clocks were striking "
3539 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3540 "effort to escape the vile wind, slipped quickly through the "
3541 "glass doors of Victory Mansions, though not quickly enough to "
3542 "prevent a swirl of gritty dust from entering along with him.")
3543
3544 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003545 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003546 # verify the content with this cert
3547 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3548 # certificate unrelated to priv_key, used to trigger an error
3549 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003550
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003551 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003552 sig = sign(priv_key, content, digest)
3553
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003554 # Verify the signature of content, will throw an exception if
3555 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003556 verify(good_cert, sig, content, digest)
3557
3558 # This should fail because the certificate doesn't match the
3559 # private key that was used to sign the content.
3560 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3561
3562 # This should fail because we've "tainted" the content after
3563 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003564 self.assertRaises(
3565 Error, verify,
3566 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003567
3568 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003569 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003570 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003571 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003572 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003573
Abraham Martinc5484ba2015-03-25 15:33:05 +00003574 def test_sign_verify_with_text(self):
3575 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003576 :py:obj:`sign` generates a cryptographic signature which
3577 :py:obj:`verify` can check. Deprecation warnings raised because using
3578 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003579 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003580 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003581 b"It was a bright cold day in April, and the clocks were striking "
3582 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3583 b"effort to escape the vile wind, slipped quickly through the "
3584 b"glass doors of Victory Mansions, though not quickly enough to "
3585 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003586 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003587
3588 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3589 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3590 for digest in ['md5', 'sha1']:
3591 with catch_warnings(record=True) as w:
3592 simplefilter("always")
3593 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003594
3595 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003596 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003597 WARNING_TYPE_EXPECTED
3598 ),
3599 str(w[-1].message)
3600 )
3601 self.assertIs(w[-1].category, DeprecationWarning)
3602
Abraham Martinc5484ba2015-03-25 15:33:05 +00003603 with catch_warnings(record=True) as w:
3604 simplefilter("always")
3605 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003606
3607 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003608 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003609 WARNING_TYPE_EXPECTED
3610 ),
3611 str(w[-1].message)
3612 )
3613 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003614
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003615 def test_sign_nulls(self):
3616 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003617 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003618 """
3619 content = b("Watch out! \0 Did you see it?")
3620 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3621 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3622 sig = sign(priv_key, content, "sha1")
3623 verify(good_cert, sig, content, "sha1")
3624
Colleen Murphye09399b2016-03-01 17:40:49 -08003625 def test_sign_with_large_key(self):
3626 """
3627 :py:obj:`sign` produces a signature for a string when using a long key.
3628 """
3629 content = b(
3630 "It was a bright cold day in April, and the clocks were striking "
3631 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3632 "effort to escape the vile wind, slipped quickly through the "
3633 "glass doors of Victory Mansions, though not quickly enough to "
3634 "prevent a swirl of gritty dust from entering along with him.")
3635
3636 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3637 sign(priv_key, content, "sha1")
3638
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003639
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003640class EllipticCurveTests(TestCase):
3641 """
3642 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3643 :py:obj:`get_elliptic_curves`.
3644 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003645
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003646 def test_set(self):
3647 """
3648 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3649 """
3650 self.assertIsInstance(get_elliptic_curves(), set)
3651
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003652 def test_some_curves(self):
3653 """
3654 If :py:mod:`cryptography` has elliptic curve support then the set
3655 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3656 it.
3657
3658 There could be an OpenSSL that violates this assumption. If so, this
3659 test will fail and we'll find out.
3660 """
3661 curves = get_elliptic_curves()
3662 if lib.Cryptography_HAS_EC:
3663 self.assertTrue(curves)
3664 else:
3665 self.assertFalse(curves)
3666
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003667 def test_a_curve(self):
3668 """
3669 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3670 supported curve.
3671 """
3672 curves = get_elliptic_curves()
3673 if curves:
3674 curve = next(iter(curves))
3675 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3676 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003677 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003678
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003679 def test_not_a_curve(self):
3680 """
3681 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3682 with a name which does not identify a supported curve.
3683 """
3684 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003685 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003686
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003687 def test_repr(self):
3688 """
3689 The string representation of a curve object includes simply states the
3690 object is a curve and what its name is.
3691 """
3692 curves = get_elliptic_curves()
3693 if curves:
3694 curve = next(iter(curves))
3695 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3696
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003697 def test_to_EC_KEY(self):
3698 """
3699 The curve object can export a version of itself as an EC_KEY* via the
3700 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3701 """
3702 curves = get_elliptic_curves()
3703 if curves:
3704 curve = next(iter(curves))
3705 # It's not easy to assert anything about this object. However, see
3706 # leakcheck/crypto.py for a test that demonstrates it at least does
3707 # not leak memory.
3708 curve._to_EC_KEY()
3709
3710
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003711class EllipticCurveFactory(object):
3712 """
3713 A helper to get the names of two curves.
3714 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003715
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003716 def __init__(self):
3717 curves = iter(get_elliptic_curves())
3718 try:
3719 self.curve_name = next(curves).name
3720 self.another_curve_name = next(curves).name
3721 except StopIteration:
3722 self.curve_name = self.another_curve_name = None
3723
3724
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003725class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3726 """
3727 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3728 """
3729 curve_factory = EllipticCurveFactory()
3730
3731 if curve_factory.curve_name is None:
3732 skip = "There are no curves available there can be no curve objects."
3733
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003734 def anInstance(self):
3735 """
3736 Get the curve object for an arbitrary curve supported by the system.
3737 """
3738 return get_elliptic_curve(self.curve_factory.curve_name)
3739
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003740 def anotherInstance(self):
3741 """
3742 Get the curve object for an arbitrary curve supported by the system -
3743 but not the one returned by C{anInstance}.
3744 """
3745 return get_elliptic_curve(self.curve_factory.another_curve_name)
3746
3747
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003748class EllipticCurveHashTests(TestCase):
3749 """
3750 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3751 as an item in a :py:type:`dict` or :py:type:`set`).
3752 """
3753 curve_factory = EllipticCurveFactory()
3754
3755 if curve_factory.curve_name is None:
3756 skip = "There are no curves available there can be no curve objects."
3757
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003758 def test_contains(self):
3759 """
3760 The ``in`` operator reports that a :py:type:`set` containing a curve
3761 does contain that curve.
3762 """
3763 curve = get_elliptic_curve(self.curve_factory.curve_name)
3764 curves = set([curve])
3765 self.assertIn(curve, curves)
3766
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003767 def test_does_not_contain(self):
3768 """
3769 The ``in`` operator reports that a :py:type:`set` not containing a
3770 curve does not contain that curve.
3771 """
3772 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003773 curves = set([
3774 get_elliptic_curve(self.curve_factory.another_curve_name)
3775 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003776 self.assertNotIn(curve, curves)
3777
3778
Rick Dean5b7b6372009-04-01 11:34:06 -05003779if __name__ == '__main__':
3780 main()