blob: d9a9526cf07cdd8985785c1653bab9b4bfbfa560 [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
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040029from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040030from OpenSSL.crypto import dump_certificate, load_certificate_request
31from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040032from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Jean-Paul Calderone9178ee62010-01-25 17:55:30 -050033from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000034from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040035from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040036from OpenSSL.crypto import (
37 sign, verify, get_elliptic_curve, get_elliptic_curves)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020038from OpenSSL._util import native, lib
39
40from .util import (
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040041 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
42)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040043
Alex Gaynoraceb3e22015-09-05 12:00:22 -040044
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040045def normalize_certificate_pem(pem):
46 return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
47
48
49def normalize_privatekey_pem(pem):
50 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
51
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040052
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050053GOOD_CIPHER = "blowfish"
54BAD_CIPHER = "zippers"
55
56GOOD_DIGEST = "MD5"
57BAD_DIGEST = "monkeys"
58
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040059root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050060MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
61BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
62ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
63NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
64MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
65ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
66urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
672xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
681dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
69FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
70VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
71BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
72b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
73AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
74hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
75w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
76-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040077""")
Rick Dean94e46fd2009-07-18 14:51:24 -050078
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040079root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050080MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
81jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
823claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
83AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
84yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
856JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
86BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
87u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
88PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
89I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
90ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
916AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
92cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
93-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040094""")
Rick Dean94e46fd2009-07-18 14:51:24 -050095
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070096intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
97MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
98WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
99DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
100ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
101dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
102MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
103AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
104FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
10521H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
106AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
107QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1089n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1099mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
110-----END CERTIFICATE-----
111""")
112
113intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
114MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
115ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
116qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
117AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
118rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
119147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
120+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
121wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
122sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
12352vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
124DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
125/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
126NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
127-----END RSA PRIVATE KEY-----
128""")
129
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400130server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500131MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
132BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
133VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
134NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
135gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
136lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
137b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
138lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
139gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
140dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1412mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
142uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
143-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400144""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500145
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400146server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500147MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
148U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
149SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
150AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
151j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
152j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
153Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
154msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
155FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1564e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1571sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
158NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
159r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
160-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400161"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500162
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700163intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
164MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
165ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
166CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
167biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
168BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
169CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
170biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
171iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
172+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
173biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
174UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1753bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
176x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
177-----END CERTIFICATE-----
178""")
179
180intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
181MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
182SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1838Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
184AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1855ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
186d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
187z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
188dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
189EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
190X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
1919UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
192ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
193nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
194-----END RSA PRIVATE KEY-----
195""")
196
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400197client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500198MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
199BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
200VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
201ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
202MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
203rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
204iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
205oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2060fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
207Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2089Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
209PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
210-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400211""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500212
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400213client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500214MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
215btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
216eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
217AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
218zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
219h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
220V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
221TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
222dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
223D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
224si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
225JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
226f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
227-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400228"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400229
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400230cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400231MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
232BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
233ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
234NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
235MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
236ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
237urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2382xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2391dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
240FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
241VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
242BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
243b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
244AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
245hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
246w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
247-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400248""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400249
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400250cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
251-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400252MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
253jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2543claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
255AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
256yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2576JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
258BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
259u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
260PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
261I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
262ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2636AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
264cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
265-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400266"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400267
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400268cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
269MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
270EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
271ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
272BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
273E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
274xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
275gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
276Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
277oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
278-----END CERTIFICATE REQUEST-----
279""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500280
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400281encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400282Proc-Type: 4,ENCRYPTED
283DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400284
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400285SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
286a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2878+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
288mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
289+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
290fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
291tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
292rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
293gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
294o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
2957SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
296MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
29711n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
298-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400299""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400300
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400301encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400302
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400303# Some PKCS#7 stuff. Generated with the openssl command line:
304#
305# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
306#
307# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400308pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400309-----BEGIN PKCS7-----
310MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
311BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
312A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
313MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
314cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
315A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
316HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
317SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
318zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
319LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
320A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
32165w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
322Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
323Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
324bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
325VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
326/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
327Ho4EzbYCOaEAMQA=
328-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400329""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400330
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700331pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700332MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
333BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
334A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
335MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
336cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
337A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
338HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
339SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
340zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
341LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
342A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
34365w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
344Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
345Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
346bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
347VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
348/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
349Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700350""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700351
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400352crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500353-----BEGIN X509 CRL-----
354MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
355SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
356D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
357MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
358MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3594dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3600yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
361vrzEeLDRiiPl92dyyWmu
362-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400363""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400364
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400365
366# A broken RSA private key which can be used to test the error path through
367# PKey.check.
368inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
369MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
3705kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
371OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
372zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
373nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
374HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
375oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
376-----END RSA PRIVATE KEY-----
377""")
378
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400379# certificate with NULL bytes in subjectAltName and common name
380
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400381nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400382MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
383DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
384eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
385RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
386ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
387NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
388DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
389ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
390ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
391hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
392BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
393pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
394vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
395KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
396oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
39708LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
398HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
399BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
400Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
401bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
402AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
403i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
404HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
405kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
406VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
407RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
408-----END CERTIFICATE-----""")
409
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400410
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400411class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400412 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900413 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400414 """
415
416 def setUp(self):
417 """
418 Create a new private key and start a certificate request (for a test
419 method to finish in one way or another).
420 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800421 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400422 # Basic setup stuff to generate a certificate
423 self.pkey = PKey()
424 self.pkey.generate_key(TYPE_RSA, 384)
425 self.req = X509Req()
426 self.req.set_pubkey(self.pkey)
427 # Authority good you have.
428 self.req.get_subject().commonName = "Yoda root CA"
429 self.x509 = X509()
430 self.subject = self.x509.get_subject()
431 self.subject.commonName = self.req.get_subject().commonName
432 self.x509.set_issuer(self.subject)
433 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400434 now = datetime.now()
435 expire = datetime.now() + timedelta(days=100)
436 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
437 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400438
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800439 def tearDown(self):
440 """
441 Forget all of the pyOpenSSL objects so they can be garbage collected,
442 their memory released, and not interfere with the leak detection code.
443 """
444 self.pkey = self.req = self.x509 = self.subject = None
445 super(X509ExtTests, self).tearDown()
446
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400447 def test_str(self):
448 """
Alex Gaynor31287502015-09-05 16:11:27 -0400449 The string representation of :py:class:`X509Extension` instances as
450 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400451 """
452 # This isn't necessarily the best string representation. Perhaps it
453 # will be changed/improved in the future.
454 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400455 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400456 'CA:FALSE')
457
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400458 def test_type(self):
459 """
Alex Gaynor31287502015-09-05 16:11:27 -0400460 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
461 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400462 """
463 self.assertIdentical(X509Extension, X509ExtensionType)
464 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400465 X509Extension,
466 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400467
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500468 def test_construction(self):
469 """
Alex Gaynor31287502015-09-05 16:11:27 -0400470 :py:class:`X509Extension` accepts an extension type name, a critical
471 flag, and an extension value and returns an
472 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500473 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400474 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500475 self.assertTrue(
476 isinstance(basic, X509ExtensionType),
477 "%r is of type %r, should be %r" % (
478 basic, type(basic), X509ExtensionType))
479
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400480 comment = X509Extension(
481 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500482 self.assertTrue(
483 isinstance(comment, X509ExtensionType),
484 "%r is of type %r, should be %r" % (
485 comment, type(comment), X509ExtensionType))
486
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500487 def test_invalid_extension(self):
488 """
Alex Gaynor31287502015-09-05 16:11:27 -0400489 :py:class:`X509Extension` raises something if it is passed a bad
490 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500491 """
492 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400493 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500494 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400495 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500496
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500497 # Exercise a weird one (an extension which uses the r2i method). This
498 # exercises the codepath that requires a non-NULL ctx to be passed to
499 # X509V3_EXT_nconf. It can't work now because we provide no
500 # configuration database. It might be made to work in the future.
501 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400502 Error, X509Extension, b('proxyCertInfo'), True,
503 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500504
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500505 def test_get_critical(self):
506 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900507 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500508 extension's critical flag.
509 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400510 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500511 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400512 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500513 self.assertFalse(ext.get_critical())
514
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500515 def test_get_short_name(self):
516 """
Alex Gaynor31287502015-09-05 16:11:27 -0400517 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
518 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500519 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400520 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
521 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
522 ext = X509Extension(b('nsComment'), True, b('foo bar'))
523 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500524
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400525 def test_get_data(self):
526 """
Alex Gaynor31287502015-09-05 16:11:27 -0400527 :py:meth:`X509Extension.get_data` returns a string giving the data of
528 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400529 """
530 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
531 # Expect to get back the DER encoded form of CA:true.
532 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
533
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400534 def test_get_data_wrong_args(self):
535 """
Alex Gaynor31287502015-09-05 16:11:27 -0400536 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
537 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400538 """
539 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
540 self.assertRaises(TypeError, ext.get_data, None)
541 self.assertRaises(TypeError, ext.get_data, "foo")
542 self.assertRaises(TypeError, ext.get_data, 7)
543
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400544 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500545 """
Alex Gaynor31287502015-09-05 16:11:27 -0400546 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
547 provided for an extension which does not use it and is ignored in this
548 case.
Rick Dean47262da2009-07-08 16:17:17 -0500549 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400550 ext1 = X509Extension(
551 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400552 self.x509.add_extensions([ext1])
553 self.x509.sign(self.pkey, 'sha1')
554 # This is a little lame. Can we think of a better way?
555 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400556 self.assertTrue(b('X509v3 Basic Constraints:') in text)
557 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400558
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400559 def test_subject(self):
560 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900561 If an extension requires a subject, the :py:data:`subject` parameter to
562 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400563 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400564 ext3 = X509Extension(
565 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400566 self.x509.add_extensions([ext3])
567 self.x509.sign(self.pkey, 'sha1')
568 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400569 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400570
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400571 def test_missing_subject(self):
572 """
Alex Gaynor31287502015-09-05 16:11:27 -0400573 If an extension requires a subject and the :py:data:`subject` parameter
574 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400575 """
576 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400577 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400578
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400579 def test_invalid_subject(self):
580 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900581 If the :py:data:`subject` parameter is given a value which is not an
582 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400583 """
584 for badObj in [True, object(), "hello", [], self]:
585 self.assertRaises(
586 TypeError,
587 X509Extension,
588 'basicConstraints', False, 'CA:TRUE', subject=badObj)
589
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400590 def test_unused_issuer(self):
591 """
Alex Gaynor31287502015-09-05 16:11:27 -0400592 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
593 provided for an extension which does not use it and is ignored in this
594 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400595 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400596 ext1 = X509Extension(
597 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400598 self.x509.add_extensions([ext1])
599 self.x509.sign(self.pkey, 'sha1')
600 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400601 self.assertTrue(b('X509v3 Basic Constraints:') in text)
602 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400603
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400604 def test_issuer(self):
605 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800606 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900607 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400608 """
609 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400610 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400611 issuer=self.x509)
612 self.x509.add_extensions([ext2])
613 self.x509.sign(self.pkey, 'sha1')
614 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400615 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
616 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400617
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400618 def test_missing_issuer(self):
619 """
Alex Gaynor31287502015-09-05 16:11:27 -0400620 If an extension requires an issue and the :py:data:`issuer` parameter
621 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400622 """
623 self.assertRaises(
624 Error,
625 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400626 b('authorityKeyIdentifier'), False,
627 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400628
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400629 def test_invalid_issuer(self):
630 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900631 If the :py:data:`issuer` parameter is given a value which is not an
632 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400633 """
634 for badObj in [True, object(), "hello", [], self]:
635 self.assertRaises(
636 TypeError,
637 X509Extension,
638 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
639 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500640
641
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400642class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500643 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900644 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500645 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400646
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400647 def test_type(self):
648 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900649 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
650 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400651 """
652 self.assertIdentical(PKey, PKeyType)
653 self.assertConsistentType(PKey, 'PKey')
654
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500655 def test_construction(self):
656 """
Alex Gaynor31287502015-09-05 16:11:27 -0400657 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
658 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500659 """
660 self.assertRaises(TypeError, PKey, None)
661 key = PKey()
662 self.assertTrue(
663 isinstance(key, PKeyType),
664 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
665
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500666 def test_pregeneration(self):
667 """
Alex Gaynor31287502015-09-05 16:11:27 -0400668 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
669 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
670 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500671 """
672 key = PKey()
673 self.assertEqual(key.type(), 0)
674 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400675 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500676
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500677 def test_failedGeneration(self):
678 """
Alex Gaynor31287502015-09-05 16:11:27 -0400679 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
680 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
681 the second giving the number of bits to generate. If an invalid type
682 is specified or generation fails, :py:exc:`Error` is raised. If an
683 invalid number of bits is specified, :py:exc:`ValueError` or
684 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500685 """
686 key = PKey()
687 self.assertRaises(TypeError, key.generate_key)
688 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
689 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
690 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500691
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500692 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
693 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500694
695 # XXX RSA generation for small values of bits is fairly buggy in a wide
696 # range of OpenSSL versions. I need to figure out what the safe lower
697 # bound for a reasonable number of OpenSSL versions is and explicitly
698 # check for that in the wrapper. The failure behavior is typically an
699 # infinite loop inside OpenSSL.
700
701 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500702
703 # XXX DSA generation seems happy with any number of bits. The DSS
704 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
705 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500706 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500707 # So, it doesn't seem possible to make generate_key fail for
708 # TYPE_DSA with a bits argument which is at least an int.
709
710 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
711
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500712 def test_rsaGeneration(self):
713 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900714 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
715 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500716 """
717 bits = 128
718 key = PKey()
719 key.generate_key(TYPE_RSA, bits)
720 self.assertEqual(key.type(), TYPE_RSA)
721 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400722 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500723
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500724 def test_dsaGeneration(self):
725 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900726 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
727 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500728 """
729 # 512 is a magic number. The DSS (Digital Signature Standard)
730 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
731 # will silently promote any value below 512 to 512.
732 bits = 512
733 key = PKey()
734 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800735 # self.assertEqual(key.type(), TYPE_DSA)
736 # self.assertEqual(key.bits(), bits)
737 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500738
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500739 def test_regeneration(self):
740 """
Alex Gaynor31287502015-09-05 16:11:27 -0400741 :py:meth:`PKeyType.generate_key` can be called multiple times on the
742 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500743 """
744 key = PKey()
745 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400746 key.generate_key(type, bits)
747 self.assertEqual(key.type(), type)
748 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500749
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400750 def test_inconsistentKey(self):
751 """
Alex Gaynor31287502015-09-05 16:11:27 -0400752 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
753 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400754 """
755 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400756 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400757
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400758 def test_check_wrong_args(self):
759 """
Alex Gaynor31287502015-09-05 16:11:27 -0400760 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
761 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400762 """
763 self.assertRaises(TypeError, PKey().check, None)
764 self.assertRaises(TypeError, PKey().check, object())
765 self.assertRaises(TypeError, PKey().check, 1)
766
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400767 def test_check_public_key(self):
768 """
769 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
770 part of the key is available.
771 """
772 # A trick to get a public-only key
773 key = PKey()
774 key.generate_key(TYPE_RSA, 512)
775 cert = X509()
776 cert.set_pubkey(key)
777 pub = cert.get_pubkey()
778 self.assertRaises(TypeError, pub.check)
779
780
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400781class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500782 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900783 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500784 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400785
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500786 def _x509name(self, **attrs):
787 # XXX There's no other way to get a new X509Name yet.
788 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400789 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400790
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500791 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400792 def key(attr):
793 return attr[1]
794 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500795 for k, v in attrs:
796 setattr(name, k, v)
797 return name
798
Rick Deane15b1472009-07-09 15:53:42 -0500799 def test_type(self):
800 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900801 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500802 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400803 self.assertIdentical(X509Name, X509NameType)
804 self.assertEqual(X509NameType.__name__, 'X509Name')
805 self.assertTrue(isinstance(X509NameType, type))
806
Rick Deane15b1472009-07-09 15:53:42 -0500807 name = self._x509name()
808 self.assertTrue(
809 isinstance(name, X509NameType),
810 "%r is of type %r, should be %r" % (
811 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500812
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400813 def test_onlyStringAttributes(self):
814 """
Alex Gaynor31287502015-09-05 16:11:27 -0400815 Attempting to set a non-:py:data:`str` attribute name on an
816 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
817 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400818 """
819 name = self._x509name()
820 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400821 # rejected. Sorry, you're wrong. unicode is automatically converted
822 # to str outside of the control of X509Name, so there's no way to
823 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800824
Alex Gaynor31287502015-09-05 16:11:27 -0400825 # Also, this used to test str subclasses, but that test is less
826 # relevant now that the implementation is in Python instead of C. Also
827 # PyPy automatically converts str subclasses to str when they are
828 # passed to setattr, so we can't test it on PyPy. Apparently CPython
829 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400830 self.assertRaises(TypeError, setattr, name, None, "hello")
831 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400832
833 def test_setInvalidAttribute(self):
834 """
Alex Gaynor31287502015-09-05 16:11:27 -0400835 Attempting to set any attribute name on an :py:class:`X509NameType`
836 instance for which no corresponding NID is defined causes
837 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400838 """
839 name = self._x509name()
840 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
841
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500842 def test_attributes(self):
843 """
Alex Gaynor31287502015-09-05 16:11:27 -0400844 :py:class:`X509NameType` instances have attributes for each standard
845 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500846 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500847 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500848 name.commonName = "foo"
849 self.assertEqual(name.commonName, "foo")
850 self.assertEqual(name.CN, "foo")
851 name.CN = "baz"
852 self.assertEqual(name.commonName, "baz")
853 self.assertEqual(name.CN, "baz")
854 name.commonName = "bar"
855 self.assertEqual(name.commonName, "bar")
856 self.assertEqual(name.CN, "bar")
857 name.CN = "quux"
858 self.assertEqual(name.commonName, "quux")
859 self.assertEqual(name.CN, "quux")
860
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500861 def test_copy(self):
862 """
Alex Gaynor31287502015-09-05 16:11:27 -0400863 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
864 with all the same attributes as an existing :py:class:`X509NameType`
865 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500866 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500867 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500868
869 copy = X509Name(name)
870 self.assertEqual(copy.commonName, "foo")
871 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500872
873 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500874 copy.commonName = "baz"
875 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500876
877 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500878 name.emailAddress = "quux@example.com"
879 self.assertEqual(copy.emailAddress, "bar@example.com")
880
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500881 def test_repr(self):
882 """
Alex Gaynor31287502015-09-05 16:11:27 -0400883 :py:func:`repr` passed an :py:class:`X509NameType` instance should
884 return a string containing a description of the type and the NIDs which
885 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500886 """
887 name = self._x509name(commonName="foo", emailAddress="bar")
888 self.assertEqual(
889 repr(name),
890 "<X509Name object '/emailAddress=bar/CN=foo'>")
891
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500892 def test_comparison(self):
893 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900894 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500895 """
896 def _equality(a, b, assertTrue, assertFalse):
897 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
898 assertFalse(a != b)
899 assertTrue(b == a)
900 assertFalse(b != a)
901
902 def assertEqual(a, b):
903 _equality(a, b, self.assertTrue, self.assertFalse)
904
905 # Instances compare equal to themselves.
906 name = self._x509name()
907 assertEqual(name, name)
908
909 # Empty instances should compare equal to each other.
910 assertEqual(self._x509name(), self._x509name())
911
912 # Instances with equal NIDs should compare equal to each other.
913 assertEqual(self._x509name(commonName="foo"),
914 self._x509name(commonName="foo"))
915
916 # Instance with equal NIDs set using different aliases should compare
917 # equal to each other.
918 assertEqual(self._x509name(commonName="foo"),
919 self._x509name(CN="foo"))
920
921 # Instances with more than one NID with the same values should compare
922 # equal to each other.
923 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
924 self._x509name(commonName="foo", OU="bar"))
925
926 def assertNotEqual(a, b):
927 _equality(a, b, self.assertFalse, self.assertTrue)
928
929 # Instances with different values for the same NID should not compare
930 # equal to each other.
931 assertNotEqual(self._x509name(CN="foo"),
932 self._x509name(CN="bar"))
933
934 # Instances with different NIDs should not compare equal to each other.
935 assertNotEqual(self._x509name(CN="foo"),
936 self._x509name(OU="foo"))
937
938 def _inequality(a, b, assertTrue, assertFalse):
939 assertTrue(a < b)
940 assertTrue(a <= b)
941 assertTrue(b > a)
942 assertTrue(b >= a)
943 assertFalse(a > b)
944 assertFalse(a >= b)
945 assertFalse(b < a)
946 assertFalse(b <= a)
947
948 def assertLessThan(a, b):
949 _inequality(a, b, self.assertTrue, self.assertFalse)
950
951 # An X509Name with a NID with a value which sorts less than the value
952 # of the same NID on another X509Name compares less than the other
953 # X509Name.
954 assertLessThan(self._x509name(CN="abc"),
955 self._x509name(CN="def"))
956
957 def assertGreaterThan(a, b):
958 _inequality(a, b, self.assertFalse, self.assertTrue)
959
960 # An X509Name with a NID with a value which sorts greater than the
961 # value of the same NID on another X509Name compares greater than the
962 # other X509Name.
963 assertGreaterThan(self._x509name(CN="def"),
964 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500965
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400966 def test_hash(self):
967 """
Alex Gaynor31287502015-09-05 16:11:27 -0400968 :py:meth:`X509Name.hash` returns an integer hash based on the value of
969 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400970 """
971 a = self._x509name(CN="foo")
972 b = self._x509name(CN="foo")
973 self.assertEqual(a.hash(), b.hash())
974 a.CN = "bar"
975 self.assertNotEqual(a.hash(), b.hash())
976
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400977 def test_der(self):
978 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900979 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400980 """
981 a = self._x509name(CN="foo", C="US")
982 self.assertEqual(
983 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400984 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +0200985 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400986
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400987 def test_get_components(self):
988 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900989 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
990 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400991 giving the NIDs and associated values which make up the name.
992 """
993 a = self._x509name()
994 self.assertEqual(a.get_components(), [])
995 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400996 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400997 a.organizationalUnitName = "bar"
998 self.assertEqual(
999 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001000 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001001
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001002 def test_load_nul_byte_attribute(self):
1003 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001004 An :py:class:`OpenSSL.crypto.X509Name` from an
1005 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001006 NUL byte in the value of one of its attributes.
1007 """
1008 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1009 subject = cert.get_subject()
1010 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001011 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001012
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001013 def test_setAttributeFailure(self):
1014 """
1015 If the value of an attribute cannot be set for some reason then
1016 :py:class:`OpenSSL.crypto.Error` is raised.
1017 """
1018 name = self._x509name()
1019 # This value is too long
1020 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1021
1022
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001023class _PKeyInteractionTestsMixin:
1024 """
1025 Tests which involve another thing and a PKey.
1026 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001027
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001028 def signable(self):
1029 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001030 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1031 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001032 """
1033 raise NotImplementedError()
1034
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001035 def test_signWithUngenerated(self):
1036 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001037 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1038 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001039 """
1040 request = self.signable()
1041 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001042 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001043
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001044 def test_signWithPublicKey(self):
1045 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001046 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1047 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001048 """
1049 request = self.signable()
1050 key = PKey()
1051 key.generate_key(TYPE_RSA, 512)
1052 request.set_pubkey(key)
1053 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001054 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001055
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001056 def test_signWithUnknownDigest(self):
1057 """
Alex Gaynor31287502015-09-05 16:11:27 -04001058 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1059 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001060 """
1061 request = self.signable()
1062 key = PKey()
1063 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001064 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001065
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001066 def test_sign(self):
1067 """
Alex Gaynor31287502015-09-05 16:11:27 -04001068 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1069 valid digest function. :py:meth:`X509Req.verify` can be used to check
1070 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001071 """
1072 request = self.signable()
1073 key = PKey()
1074 key.generate_key(TYPE_RSA, 512)
1075 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001076 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001077 # If the type has a verify method, cover that too.
1078 if getattr(request, 'verify', None) is not None:
1079 pub = request.get_pubkey()
1080 self.assertTrue(request.verify(pub))
1081 # Make another key that won't verify.
1082 key = PKey()
1083 key.generate_key(TYPE_RSA, 512)
1084 self.assertRaises(Error, request.verify, key)
1085
1086
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001087class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001088 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001089 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001090 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001091
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001092 def signable(self):
1093 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001094 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001095 """
1096 return X509Req()
1097
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001098 def test_type(self):
1099 """
Alex Gaynor31287502015-09-05 16:11:27 -04001100 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1101 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001102 """
1103 self.assertIdentical(X509Req, X509ReqType)
1104 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001105
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001106 def test_construction(self):
1107 """
Alex Gaynor31287502015-09-05 16:11:27 -04001108 :py:obj:`X509Req` takes no arguments and returns an
1109 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001110 """
1111 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001112 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001113
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001114 def test_version(self):
1115 """
Alex Gaynor31287502015-09-05 16:11:27 -04001116 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1117 certificate request. :py:obj:`X509ReqType.get_version` returns the
1118 X.509 version of the certificate request. The initial value of the
1119 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001120 """
1121 request = X509Req()
1122 self.assertEqual(request.get_version(), 0)
1123 request.set_version(1)
1124 self.assertEqual(request.get_version(), 1)
1125 request.set_version(3)
1126 self.assertEqual(request.get_version(), 3)
1127
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001128 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001129 """
Alex Gaynor31287502015-09-05 16:11:27 -04001130 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1131 with the wrong number of arguments or with a non-:py:obj:`int`
1132 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1133 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001134 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001135 request = X509Req()
1136 self.assertRaises(TypeError, request.set_version)
1137 self.assertRaises(TypeError, request.set_version, "foo")
1138 self.assertRaises(TypeError, request.set_version, 1, 2)
1139 self.assertRaises(TypeError, request.get_version, None)
1140
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001141 def test_get_subject(self):
1142 """
Alex Gaynor31287502015-09-05 16:11:27 -04001143 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1144 subject of the request and which is valid even after the request object
1145 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001146 """
1147 request = X509Req()
1148 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001149 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001150 subject.commonName = "foo"
1151 self.assertEqual(request.get_subject().commonName, "foo")
1152 del request
1153 subject.commonName = "bar"
1154 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001155
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001156 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001157 """
Alex Gaynor31287502015-09-05 16:11:27 -04001158 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1159 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001160 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001161 request = X509Req()
1162 self.assertRaises(TypeError, request.get_subject, None)
1163
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001164 def test_add_extensions(self):
1165 """
Alex Gaynor31287502015-09-05 16:11:27 -04001166 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1167 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001168 """
1169 request = X509Req()
1170 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001171 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001172 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001173 self.assertEqual(len(exts), 1)
1174 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1175 self.assertEqual(exts[0].get_critical(), 1)
1176 self.assertEqual(exts[0].get_data(), b('0\x00'))
1177
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001178 def test_get_extensions(self):
1179 """
1180 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1181 extensions added to this X509 request.
1182 """
1183 request = X509Req()
1184 exts = request.get_extensions()
1185 self.assertEqual(exts, [])
1186 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001187 X509Extension(b('basicConstraints'), True, b('CA:true')),
1188 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001189 exts = request.get_extensions()
1190 self.assertEqual(len(exts), 2)
1191 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1192 self.assertEqual(exts[0].get_critical(), 1)
1193 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1194 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1195 self.assertEqual(exts[1].get_critical(), 0)
1196 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001197
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001198 def test_add_extensions_wrong_args(self):
1199 """
Alex Gaynor31287502015-09-05 16:11:27 -04001200 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1201 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1202 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1203 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001204 """
1205 request = X509Req()
1206 self.assertRaises(TypeError, request.add_extensions)
1207 self.assertRaises(TypeError, request.add_extensions, object())
1208 self.assertRaises(ValueError, request.add_extensions, [object()])
1209 self.assertRaises(TypeError, request.add_extensions, [], None)
1210
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001211 def test_verify_wrong_args(self):
1212 """
1213 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1214 arguments or more than one argument or if passed anything other than a
1215 :py:obj:`PKey` instance as its single argument.
1216 """
1217 request = X509Req()
1218 self.assertRaises(TypeError, request.verify)
1219 self.assertRaises(TypeError, request.verify, object())
1220 self.assertRaises(TypeError, request.verify, PKey(), object())
1221
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001222 def test_verify_uninitialized_key(self):
1223 """
Alex Gaynor31287502015-09-05 16:11:27 -04001224 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1225 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001226 """
1227 request = X509Req()
1228 pkey = PKey()
1229 self.assertRaises(Error, request.verify, pkey)
1230
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001231 def test_verify_wrong_key(self):
1232 """
Alex Gaynor31287502015-09-05 16:11:27 -04001233 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1234 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1235 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001236 """
1237 request = X509Req()
1238 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001239 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001240 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1241 self.assertRaises(Error, request.verify, another_pkey)
1242
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001243 def test_verify_success(self):
1244 """
1245 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001246 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1247 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001248 """
1249 request = X509Req()
1250 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001251 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001252 self.assertEqual(True, request.verify(pkey))
1253
1254
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001255class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001256 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001257 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001258 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001259 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001260
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001261 extpem = """
1262-----BEGIN CERTIFICATE-----
1263MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1264BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1265eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1266MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1267aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1268hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1269Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1270zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1271hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1272TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
127303HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1274MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1275b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1276MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1277uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1278WpOdIpB8KksUTCzV591Nr1wd
1279-----END CERTIFICATE-----
1280 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001281
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001282 def signable(self):
1283 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001284 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001285 """
1286 return X509()
1287
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001288 def test_type(self):
1289 """
Alex Gaynor31287502015-09-05 16:11:27 -04001290 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1291 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001292 """
1293 self.assertIdentical(X509, X509Type)
1294 self.assertConsistentType(X509, 'X509')
1295
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001296 def test_construction(self):
1297 """
Alex Gaynor31287502015-09-05 16:11:27 -04001298 :py:obj:`X509` takes no arguments and returns an instance of
1299 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001300 """
1301 certificate = X509()
1302 self.assertTrue(
1303 isinstance(certificate, X509Type),
1304 "%r is of type %r, should be %r" % (certificate,
1305 type(certificate),
1306 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001307 self.assertEqual(type(X509Type).__name__, 'type')
1308 self.assertEqual(type(certificate).__name__, 'X509')
1309 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001310 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001311
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001312 def test_get_version_wrong_args(self):
1313 """
Alex Gaynor31287502015-09-05 16:11:27 -04001314 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1315 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001316 """
1317 cert = X509()
1318 self.assertRaises(TypeError, cert.get_version, None)
1319
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001320 def test_set_version_wrong_args(self):
1321 """
Alex Gaynor31287502015-09-05 16:11:27 -04001322 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1323 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001324 """
1325 cert = X509()
1326 self.assertRaises(TypeError, cert.set_version)
1327 self.assertRaises(TypeError, cert.set_version, None)
1328 self.assertRaises(TypeError, cert.set_version, 1, None)
1329
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001330 def test_version(self):
1331 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001332 :py:obj:`X509.set_version` sets the certificate version number.
1333 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001334 """
1335 cert = X509()
1336 cert.set_version(1234)
1337 self.assertEquals(cert.get_version(), 1234)
1338
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001339 def test_get_serial_number_wrong_args(self):
1340 """
Alex Gaynor31287502015-09-05 16:11:27 -04001341 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1342 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001343 """
1344 cert = X509()
1345 self.assertRaises(TypeError, cert.get_serial_number, None)
1346
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001347 def test_serial_number(self):
1348 """
Alex Gaynor31287502015-09-05 16:11:27 -04001349 The serial number of an :py:obj:`X509Type` can be retrieved and
1350 modified with :py:obj:`X509Type.get_serial_number` and
1351 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001352 """
1353 certificate = X509()
1354 self.assertRaises(TypeError, certificate.set_serial_number)
1355 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1356 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1357 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1358 self.assertEqual(certificate.get_serial_number(), 0)
1359 certificate.set_serial_number(1)
1360 self.assertEqual(certificate.get_serial_number(), 1)
1361 certificate.set_serial_number(2 ** 32 + 1)
1362 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1363 certificate.set_serial_number(2 ** 64 + 1)
1364 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001365 certificate.set_serial_number(2 ** 128 + 1)
1366 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1367
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001368 def _setBoundTest(self, which):
1369 """
Alex Gaynor31287502015-09-05 16:11:27 -04001370 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1371 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1372 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001373 """
1374 certificate = X509()
1375 set = getattr(certificate, 'set_not' + which)
1376 get = getattr(certificate, 'get_not' + which)
1377
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001378 # Starts with no value.
1379 self.assertEqual(get(), None)
1380
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001381 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001382 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001383 set(when)
1384 self.assertEqual(get(), when)
1385
1386 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001387 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001388 set(when)
1389 self.assertEqual(get(), when)
1390
1391 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001392 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001393 set(when)
1394 self.assertEqual(get(), when)
1395
1396 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001397 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001398
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001399 # The wrong number of arguments results in a TypeError.
1400 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001401 with pytest.raises(TypeError):
1402 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001403 self.assertRaises(TypeError, get, b("foo bar"))
1404
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001405 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001406
1407 def test_set_notBefore(self):
1408 """
Alex Gaynor31287502015-09-05 16:11:27 -04001409 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1410 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1411 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001412 """
1413 self._setBoundTest("Before")
1414
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001415 def test_set_notAfter(self):
1416 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001417 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001418 GENERALIZEDTIME and sets the end of the certificate's validity period
1419 to it.
1420 """
1421 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001422
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001423 def test_get_notBefore(self):
1424 """
Alex Gaynor31287502015-09-05 16:11:27 -04001425 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1426 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001427 internally.
1428 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001429 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001430 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001431
Rick Dean38a05c82009-07-18 01:41:30 -05001432 def test_get_notAfter(self):
1433 """
Alex Gaynor31287502015-09-05 16:11:27 -04001434 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1435 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001436 internally.
1437 """
1438 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001439 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001440
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001441 def test_gmtime_adj_notBefore_wrong_args(self):
1442 """
Alex Gaynor31287502015-09-05 16:11:27 -04001443 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1444 called with the wrong number of arguments or a non-:py:obj:`int`
1445 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001446 """
1447 cert = X509()
1448 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1449 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1450 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1451
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001452 def test_gmtime_adj_notBefore(self):
1453 """
Alex Gaynor31287502015-09-05 16:11:27 -04001454 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1455 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001456 """
1457 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001458 not_before_min = (
1459 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1460 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001461 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001462 not_before = datetime.strptime(
1463 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1464 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001465 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1466 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001467
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001468 def test_gmtime_adj_notAfter_wrong_args(self):
1469 """
Alex Gaynor31287502015-09-05 16:11:27 -04001470 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1471 called with the wrong number of arguments or a non-:py:obj:`int`
1472 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001473 """
1474 cert = X509()
1475 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1476 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1477 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1478
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001479 def test_gmtime_adj_notAfter(self):
1480 """
Alex Gaynor31287502015-09-05 16:11:27 -04001481 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1482 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001483 """
1484 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001485 not_after_min = (
1486 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1487 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001488 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001489 not_after = datetime.strptime(
1490 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1491 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001492 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1493 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001494
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001495 def test_has_expired_wrong_args(self):
1496 """
Alex Gaynor31287502015-09-05 16:11:27 -04001497 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1498 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001499 """
1500 cert = X509()
1501 self.assertRaises(TypeError, cert.has_expired, None)
1502
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001503 def test_has_expired(self):
1504 """
Alex Gaynor31287502015-09-05 16:11:27 -04001505 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1506 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001507 """
1508 cert = X509()
1509 cert.gmtime_adj_notAfter(-1)
1510 self.assertTrue(cert.has_expired())
1511
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001512 def test_has_not_expired(self):
1513 """
Alex Gaynor31287502015-09-05 16:11:27 -04001514 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1515 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001516 """
1517 cert = X509()
1518 cert.gmtime_adj_notAfter(2)
1519 self.assertFalse(cert.has_expired())
1520
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001521 def test_root_has_not_expired(self):
1522 """
Alex Gaynor31287502015-09-05 16:11:27 -04001523 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1524 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001525 """
1526 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1527 self.assertFalse(cert.has_expired())
1528
Rick Dean38a05c82009-07-18 01:41:30 -05001529 def test_digest(self):
1530 """
Alex Gaynor31287502015-09-05 16:11:27 -04001531 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1532 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001533 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001534 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001535 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001536 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1537 # actually matters to the assertion (ie, another arbitrary, good
1538 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001539 # Digest verified with the command:
1540 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001541 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001542 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001543
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001544 def _extcert(self, pkey, extensions):
1545 cert = X509()
1546 cert.set_pubkey(pkey)
1547 cert.get_subject().commonName = "Unit Tests"
1548 cert.get_issuer().commonName = "Unit Tests"
1549 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1550 cert.set_notBefore(when)
1551 cert.set_notAfter(when)
1552
1553 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001554 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001555 return load_certificate(
1556 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1557
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001558 def test_extension_count(self):
1559 """
Alex Gaynor31287502015-09-05 16:11:27 -04001560 :py:obj:`X509.get_extension_count` returns the number of extensions
1561 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001562 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001563 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001564 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1565 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001566 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001567 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001568
1569 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001570 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001571 self.assertEqual(c.get_extension_count(), 0)
1572
1573 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001574 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001575 self.assertEqual(c.get_extension_count(), 1)
1576
1577 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001578 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001579 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001580
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001581 def test_get_extension(self):
1582 """
Alex Gaynor31287502015-09-05 16:11:27 -04001583 :py:obj:`X509.get_extension` takes an integer and returns an
1584 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001585 """
1586 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001587 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1588 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001589 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001590 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001591
1592 cert = self._extcert(pkey, [ca, key, subjectAltName])
1593
1594 ext = cert.get_extension(0)
1595 self.assertTrue(isinstance(ext, X509Extension))
1596 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001597 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001598
1599 ext = cert.get_extension(1)
1600 self.assertTrue(isinstance(ext, X509Extension))
1601 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001602 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001603
1604 ext = cert.get_extension(2)
1605 self.assertTrue(isinstance(ext, X509Extension))
1606 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001607 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001608
1609 self.assertRaises(IndexError, cert.get_extension, -1)
1610 self.assertRaises(IndexError, cert.get_extension, 4)
1611 self.assertRaises(TypeError, cert.get_extension, "hello")
1612
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001613 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001614 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001615 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001616 bytes and this value is reflected in the string representation of the
1617 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001618 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001619 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001620
1621 ext = cert.get_extension(3)
1622 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001623 self.assertEqual(
1624 b("DNS:altnull.python.org\x00example.com, "
1625 "email:null@python.org\x00user@example.org, "
1626 "URI:http://null.python.org\x00http://example.org, "
1627 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1628 b(str(ext)))
1629
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001630 def test_invalid_digest_algorithm(self):
1631 """
Alex Gaynor31287502015-09-05 16:11:27 -04001632 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1633 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001634 """
1635 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001636 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001637
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001638 def test_get_subject_wrong_args(self):
1639 """
Alex Gaynor31287502015-09-05 16:11:27 -04001640 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1641 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001642 """
1643 cert = X509()
1644 self.assertRaises(TypeError, cert.get_subject, None)
1645
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001646 def test_get_subject(self):
1647 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001648 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001649 """
1650 cert = load_certificate(FILETYPE_PEM, self.pemData)
1651 subj = cert.get_subject()
1652 self.assertTrue(isinstance(subj, X509Name))
1653 self.assertEquals(
1654 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001655 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1656 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001657
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001658 def test_set_subject_wrong_args(self):
1659 """
Alex Gaynor31287502015-09-05 16:11:27 -04001660 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1661 the wrong number of arguments or an argument not of type
1662 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001663 """
1664 cert = X509()
1665 self.assertRaises(TypeError, cert.set_subject)
1666 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001667 with pytest.raises(TypeError):
1668 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001669
1670 def test_set_subject(self):
1671 """
Alex Gaynor31287502015-09-05 16:11:27 -04001672 :py:obj:`X509.set_subject` changes the subject of the certificate to
1673 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001674 """
1675 cert = X509()
1676 name = cert.get_subject()
1677 name.C = 'AU'
1678 name.O = 'Unit Tests'
1679 cert.set_subject(name)
1680 self.assertEquals(
1681 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001682 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001683
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001684 def test_get_issuer_wrong_args(self):
1685 """
Alex Gaynor31287502015-09-05 16:11:27 -04001686 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1687 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001688 """
1689 cert = X509()
1690 self.assertRaises(TypeError, cert.get_issuer, None)
1691
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001692 def test_get_issuer(self):
1693 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001694 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001695 """
1696 cert = load_certificate(FILETYPE_PEM, self.pemData)
1697 subj = cert.get_issuer()
1698 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001699 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001700 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001701 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001702 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1703 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001704
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001705 def test_set_issuer_wrong_args(self):
1706 """
Alex Gaynor31287502015-09-05 16:11:27 -04001707 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1708 the wrong number of arguments or an argument not of type
1709 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001710 """
1711 cert = X509()
1712 self.assertRaises(TypeError, cert.set_issuer)
1713 self.assertRaises(TypeError, cert.set_issuer, None)
1714 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1715
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001716 def test_set_issuer(self):
1717 """
Alex Gaynor31287502015-09-05 16:11:27 -04001718 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1719 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001720 """
1721 cert = X509()
1722 name = cert.get_issuer()
1723 name.C = 'AU'
1724 name.O = 'Unit Tests'
1725 cert.set_issuer(name)
1726 self.assertEquals(
1727 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001728 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001729
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001730 def test_get_pubkey_uninitialized(self):
1731 """
Alex Gaynor31287502015-09-05 16:11:27 -04001732 When called on a certificate with no public key,
1733 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001734 """
1735 cert = X509()
1736 self.assertRaises(Error, cert.get_pubkey)
1737
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001738 def test_subject_name_hash_wrong_args(self):
1739 """
Alex Gaynor31287502015-09-05 16:11:27 -04001740 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1741 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001742 """
1743 cert = X509()
1744 self.assertRaises(TypeError, cert.subject_name_hash, None)
1745
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001746 def test_subject_name_hash(self):
1747 """
Alex Gaynor31287502015-09-05 16:11:27 -04001748 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1749 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001750 """
1751 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001752 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001753 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001754 [3350047874, # OpenSSL 0.9.8, MD5
1755 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001756 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001757
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001758 def test_get_signature_algorithm(self):
1759 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001760 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001761 the algorithm used to sign the certificate.
1762 """
1763 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001764 self.assertEqual(
1765 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001766
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001767 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001768 """
Alex Gaynor31287502015-09-05 16:11:27 -04001769 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1770 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001771 """
1772 # This certificate has been modified to indicate a bogus OID in the
1773 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001774 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001775-----BEGIN CERTIFICATE-----
1776MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1777EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1778cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1779MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1780EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1781CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1782AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1783+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1784hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1785BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1786FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1787dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1788aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1789MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1790jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1791PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1792tgI5
1793-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001794""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001795 cert = load_certificate(FILETYPE_PEM, certPEM)
1796 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001797
1798
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001799class X509StoreTests(TestCase):
1800 """
1801 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1802 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001803
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001804 def test_type(self):
1805 """
1806 :py:obj:`X509StoreType` is a type object.
1807 """
1808 self.assertIdentical(X509Store, X509StoreType)
1809 self.assertConsistentType(X509Store, 'X509Store')
1810
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001811 def test_add_cert_wrong_args(self):
1812 store = X509Store()
1813 self.assertRaises(TypeError, store.add_cert)
1814 self.assertRaises(TypeError, store.add_cert, object())
1815 self.assertRaises(TypeError, store.add_cert, X509(), object())
1816
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001817 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001818 """
1819 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1820 certificate store.
1821 """
1822 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001823 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001824 store.add_cert(cert)
1825
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001826 def test_add_cert_rejects_duplicate(self):
1827 """
Alex Gaynor31287502015-09-05 16:11:27 -04001828 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1829 an attempt is made to add the same certificate to the store more than
1830 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001831 """
1832 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1833 store = X509Store()
1834 store.add_cert(cert)
1835 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001836
1837
Rick Dean623ee362009-07-17 12:22:16 -05001838class PKCS12Tests(TestCase):
1839 """
Alex Gaynor31287502015-09-05 16:11:27 -04001840 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1841 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001842 """
1843 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1844
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001845 def test_type(self):
1846 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001847 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001848 """
1849 self.assertIdentical(PKCS12, PKCS12Type)
1850 self.assertConsistentType(PKCS12, 'PKCS12')
1851
Rick Deanf94096c2009-07-18 14:23:06 -05001852 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001853 """
Alex Gaynor31287502015-09-05 16:11:27 -04001854 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1855 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001856 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001857 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001858 self.assertEqual(None, p12.get_certificate())
1859 self.assertEqual(None, p12.get_privatekey())
1860 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001861 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001862
1863 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001864 """
Alex Gaynor31287502015-09-05 16:11:27 -04001865 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1866 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1867 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1868 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001869 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001870 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001871 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001872 self.assertRaises(TypeError, p12.set_certificate, PKey())
1873 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001874 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001875 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1876 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001877 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1878 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1879 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001880 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001881 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1882 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001883
1884 def test_key_only(self):
1885 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001886 A :py:obj:`PKCS12` with only a private key can be exported using
1887 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001888 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001889 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001890 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001891 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001892 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05001893 self.assertEqual(None, p12.get_certificate())
1894 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001895 try:
1896 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1897 except Error:
1898 # Some versions of OpenSSL will throw an exception
1899 # for this nearly useless PKCS12 we tried to generate:
1900 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1901 return
Rick Dean623ee362009-07-17 12:22:16 -05001902 p12 = load_pkcs12(dumped_p12, passwd)
1903 self.assertEqual(None, p12.get_ca_certificates())
1904 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001905
1906 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1907 # future this will be improved.
1908 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05001909
1910 def test_cert_only(self):
1911 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001912 A :py:obj:`PKCS12` with only a certificate can be exported using
1913 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001914 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001915 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001916 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001917 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001918 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05001919 self.assertEqual(cert, p12.get_certificate())
1920 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001921 try:
1922 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1923 except Error:
1924 # Some versions of OpenSSL will throw an exception
1925 # for this nearly useless PKCS12 we tried to generate:
1926 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1927 return
Rick Dean623ee362009-07-17 12:22:16 -05001928 p12 = load_pkcs12(dumped_p12, passwd)
1929 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001930
1931 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
1932 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1933
1934 # Oh ho. It puts the certificate into the ca certificates list, in
1935 # fact. Totally bogus, I would think. Nevertheless, let's exploit
1936 # that to check to see if it reconstructed the certificate we expected
1937 # it to. At some point, hopefully this will change so that
1938 # p12.get_certificate() is actually what returns the loaded
1939 # certificate.
1940 self.assertEqual(
1941 cleartextCertificatePEM,
1942 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05001943
Alex Gaynor31287502015-09-05 16:11:27 -04001944 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
1945 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05001946 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001947 Generate a PKCS12 object with components from PEM. Verify that the set
1948 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05001949 """
Rick Deanf94096c2009-07-18 14:23:06 -05001950 p12 = PKCS12()
1951 if cert_pem:
1952 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1953 self.assertEqual(ret, None)
1954 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001955 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05001956 self.assertEqual(ret, None)
1957 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04001958 ret = p12.set_ca_certificates(
1959 (load_certificate(FILETYPE_PEM, ca_pem),)
1960 )
Rick Deanf94096c2009-07-18 14:23:06 -05001961 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001962 if friendly_name:
1963 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05001964 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05001965 return p12
1966
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001967 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001968 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05001969 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001970 Use openssl program to confirm three components are recoverable from a
1971 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05001972 """
1973 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001974 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001975 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
1976 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001977 self.assertEqual(recovered_key[-len(key):], key)
1978 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001979 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001980 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
1981 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001982 self.assertEqual(recovered_cert[-len(cert):], cert)
1983 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001984 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001985 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
1986 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001987 self.assertEqual(recovered_cert[-len(ca):], ca)
1988
Stephen Holsapple38482622014-04-05 20:29:34 -07001989 def verify_pkcs12_container(self, p12):
1990 """
1991 Verify that the PKCS#12 container contains the correct client
1992 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04001993
1994 :param p12: The PKCS12 instance to verify.
1995 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07001996 """
1997 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
1998 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04001999 self.assertEqual(
2000 (client_cert_pem, client_key_pem, None),
2001 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002002
Rick Deanf94096c2009-07-18 14:23:06 -05002003 def test_load_pkcs12(self):
2004 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002005 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002006 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002007 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002008 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002009 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002010 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002011 pem,
2012 b"pkcs12",
2013 b"-export",
2014 b"-clcerts",
2015 b"-passout",
2016 b"pass:" + passwd
2017 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002018 p12 = load_pkcs12(p12_str, passphrase=passwd)
2019 self.verify_pkcs12_container(p12)
2020
Abraham Martinc5484ba2015-03-25 15:33:05 +00002021 def test_load_pkcs12_text_passphrase(self):
2022 """
2023 A PKCS12 string generated using the openssl command line can be loaded
2024 with :py:obj:`load_pkcs12` and its components extracted and examined.
2025 Using text as passphrase instead of bytes. DeprecationWarning expected.
2026 """
2027 pem = client_key_pem + client_cert_pem
2028 passwd = b"whatever"
2029 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2030 b"-passout", b"pass:" + passwd)
2031 with catch_warnings(record=True) as w:
2032 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002033 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002034
2035 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002036 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002037 WARNING_TYPE_EXPECTED
2038 ),
2039 str(w[-1].message)
2040 )
2041 self.assertIs(w[-1].category, DeprecationWarning)
2042
Abraham Martinc5484ba2015-03-25 15:33:05 +00002043 self.verify_pkcs12_container(p12)
2044
Stephen Holsapple38482622014-04-05 20:29:34 -07002045 def test_load_pkcs12_no_passphrase(self):
2046 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002047 A PKCS12 string generated using openssl command line can be loaded with
2048 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2049 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002050 """
2051 pem = client_key_pem + client_cert_pem
2052 p12_str = _runopenssl(
2053 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2054 p12 = load_pkcs12(p12_str)
2055 self.verify_pkcs12_container(p12)
2056
Stephen Holsapple38482622014-04-05 20:29:34 -07002057 def _dump_and_load(self, dump_passphrase, load_passphrase):
2058 """
2059 A helper method to dump and load a PKCS12 object.
2060 """
2061 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2062 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2063 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2064
Stephen Holsapple38482622014-04-05 20:29:34 -07002065 def test_load_pkcs12_null_passphrase_load_empty(self):
2066 """
2067 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002068 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002069 extracted and examined.
2070 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002071 self.verify_pkcs12_container(
2072 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002073
Stephen Holsapple38482622014-04-05 20:29:34 -07002074 def test_load_pkcs12_null_passphrase_load_null(self):
2075 """
2076 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002077 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002078 extracted and examined.
2079 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002080 self.verify_pkcs12_container(
2081 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002082
Stephen Holsapple38482622014-04-05 20:29:34 -07002083 def test_load_pkcs12_empty_passphrase_load_empty(self):
2084 """
2085 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002086 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002087 extracted and examined.
2088 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002089 self.verify_pkcs12_container(
2090 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002091
Stephen Holsapple38482622014-04-05 20:29:34 -07002092 def test_load_pkcs12_empty_passphrase_load_null(self):
2093 """
2094 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002095 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002096 extracted and examined.
2097 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002098 self.verify_pkcs12_container(
2099 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002100
Rick Deanee568302009-07-24 09:56:29 -05002101 def test_load_pkcs12_garbage(self):
2102 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002103 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2104 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002105 """
2106 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002107 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002108 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2109 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002110
Rick Deanf94096c2009-07-18 14:23:06 -05002111 def test_replace(self):
2112 """
Alex Gaynor31287502015-09-05 16:11:27 -04002113 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2114 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002115 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002116 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002117 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2118 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2119 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002120 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002121 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002122 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002123 self.assertEqual(1, len(p12.get_ca_certificates()))
2124 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002125 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002126 self.assertEqual(2, len(p12.get_ca_certificates()))
2127 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2128 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2129
Rick Deanf94096c2009-07-18 14:23:06 -05002130 def test_friendly_name(self):
2131 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002132 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002133 :py:obj:`PKCS12.get_friendlyname` and
2134 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2135 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002136 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002137 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002138 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002139 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002140 p12.set_friendlyname(friendly_name)
2141 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002142 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002143 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002144 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002145 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002146 # We would use the openssl program to confirm the friendly
2147 # name, but it is not possible. The pkcs12 command
2148 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002149 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002150 self.check_recovery(
2151 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2152 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002153
Rick Deanf94096c2009-07-18 14:23:06 -05002154 def test_various_empty_passphrases(self):
2155 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002156 Test that missing, None, and '' passphrases are identical for PKCS12
2157 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002158 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002159 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002160 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002161 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2162 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2163 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2164 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2165 self.check_recovery(
2166 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2167 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002168
Rick Deanf94096c2009-07-18 14:23:06 -05002169 def test_removing_ca_cert(self):
2170 """
Alex Gaynor31287502015-09-05 16:11:27 -04002171 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2172 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002173 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002174 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2175 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002176 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002177
Rick Deanf94096c2009-07-18 14:23:06 -05002178 def test_export_without_mac(self):
2179 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002180 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002181 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002182 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002183 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002184 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002185 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002186 self.check_recovery(
2187 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002188 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002189
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002190 def test_load_without_mac(self):
2191 """
2192 Loading a PKCS12 without a MAC does something other than crash.
2193 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002194 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002195 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2196 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002197 try:
2198 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2199 # The person who generated this PCKS12 should be flogged,
2200 # or better yet we should have a means to determine
2201 # whether a PCKS12 had a MAC that was verified.
2202 # Anyway, libopenssl chooses to allow it, so the
2203 # pyopenssl binding does as well.
2204 self.assertTrue(isinstance(recovered_p12, PKCS12))
2205 except Error:
2206 # Failing here with an exception is preferred as some openssl
2207 # versions do.
2208 pass
Rick Dean623ee362009-07-17 12:22:16 -05002209
Rick Dean25bcc1f2009-07-20 11:53:13 -05002210 def test_zero_len_list_for_ca(self):
2211 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002212 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002213 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002214 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002215 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002216 p12.set_ca_certificates([])
2217 self.assertEqual((), p12.get_ca_certificates())
2218 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2219 self.check_recovery(
2220 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2221 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002222
Rick Deanf94096c2009-07-18 14:23:06 -05002223 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002224 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002225 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002226 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002227 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002228 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002229 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002230 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002231
Abraham Martinc5484ba2015-03-25 15:33:05 +00002232 def test_export_without_bytes(self):
2233 """
2234 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2235 """
2236 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2237
2238 with catch_warnings(record=True) as w:
2239 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002240 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002241 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002242 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002243 WARNING_TYPE_EXPECTED
2244 ),
2245 str(w[-1].message)
2246 )
2247 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002248 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002249 dumped_p12,
2250 key=server_key_pem,
2251 cert=server_cert_pem,
2252 passwd=b"randomtext"
2253 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002254
Rick Deanf94096c2009-07-18 14:23:06 -05002255 def test_key_cert_mismatch(self):
2256 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002257 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002258 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002259 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002260 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2261 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002262
2263
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002264# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002265_cmdLineQuoteRe = re.compile(br'(\\*)"')
2266_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002267
2268
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002269def cmdLineQuote(s):
2270 """
2271 Internal method for quoting a single command-line argument.
2272
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002273 See http://www.perlmonks.org/?node_id=764004
2274
Jonathan Ballet648875f2011-07-16 14:14:58 +09002275 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002276 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002277 cmd.exe-style quoting
2278
Jonathan Ballet648875f2011-07-16 14:14:58 +09002279 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002280 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002281 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002282 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2283 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002284
2285
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002286def quoteArguments(arguments):
2287 """
2288 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002289 a similar API. This allows the list passed to
2290 :py:obj:`reactor.spawnProcess` to match the child process's
2291 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002292
Jonathan Ballet648875f2011-07-16 14:14:58 +09002293 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002294 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002295
Jonathan Ballet648875f2011-07-16 14:14:58 +09002296 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002297 :return: A space-delimited string containing quoted versions of
2298 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002299 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002300 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002301
2302
Rick Dean4c9ad612009-07-17 15:05:22 -05002303def _runopenssl(pem, *args):
2304 """
2305 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002306 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002307 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002308 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002309 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002310 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2311 for arg in args
2312 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002313 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002314 command = b"openssl " + quoteArguments(args)
2315 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002316 proc.stdin.write(pem)
2317 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002318 output = proc.stdout.read()
2319 proc.stdout.close()
2320 proc.wait()
2321 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002322
2323
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002324class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002325 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002326 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002327 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002328
2329 def test_load_privatekey_invalid_format(self):
2330 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002331 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2332 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002333 """
2334 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2335
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002336 def test_load_privatekey_invalid_passphrase_type(self):
2337 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002338 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2339 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002340 """
2341 self.assertRaises(
2342 TypeError,
2343 load_privatekey,
2344 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2345
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002346 def test_load_privatekey_wrong_args(self):
2347 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002348 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2349 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002350 """
2351 self.assertRaises(TypeError, load_privatekey)
2352
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002353 def test_load_privatekey_wrongPassphrase(self):
2354 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002355 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2356 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002357 """
2358 self.assertRaises(
2359 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002360 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002361
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002362 def test_load_privatekey_passphraseWrongType(self):
2363 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002364 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2365 a passphrase with a private key encoded in a format, that doesn't
2366 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002367 """
2368 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2369 blob = dump_privatekey(FILETYPE_ASN1, key)
2370 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002371 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002372
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002373 def test_load_privatekey_passphrase(self):
2374 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002375 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2376 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002377 """
2378 key = load_privatekey(
2379 FILETYPE_PEM, encryptedPrivateKeyPEM,
2380 encryptedPrivateKeyPEMPassphrase)
2381 self.assertTrue(isinstance(key, PKeyType))
2382
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002383 def test_load_privatekey_passphrase_exception(self):
2384 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002385 If the passphrase callback raises an exception, that exception is
2386 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002387 """
2388 def cb(ignored):
2389 raise ArithmeticError
2390
Alex Gaynor791212d2015-09-05 15:46:08 -04002391 with pytest.raises(ArithmeticError):
2392 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002393
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002394 def test_load_privatekey_wrongPassphraseCallback(self):
2395 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002396 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2397 is passed an encrypted PEM and a passphrase callback which returns an
2398 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002399 """
2400 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002401
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002402 def cb(*a):
2403 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002404 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002405 self.assertRaises(
2406 Error,
2407 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2408 self.assertTrue(called)
2409
2410 def test_load_privatekey_passphraseCallback(self):
2411 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002412 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2413 encrypted PEM string if given a passphrase callback which returns the
2414 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002415 """
2416 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002417
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002418 def cb(writing):
2419 called.append(writing)
2420 return encryptedPrivateKeyPEMPassphrase
2421 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2422 self.assertTrue(isinstance(key, PKeyType))
2423 self.assertEqual(called, [False])
2424
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002425 def test_load_privatekey_passphrase_wrong_return_type(self):
2426 """
2427 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2428 callback returns something other than a byte string.
2429 """
2430 self.assertRaises(
2431 ValueError,
2432 load_privatekey,
2433 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2434
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002435 def test_dump_privatekey_wrong_args(self):
2436 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002437 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2438 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002439 """
2440 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002441 # If cipher name is given, password is required.
2442 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002443 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002444
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002445 def test_dump_privatekey_unknown_cipher(self):
2446 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002447 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2448 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002449 """
2450 key = PKey()
2451 key.generate_key(TYPE_RSA, 512)
2452 self.assertRaises(
2453 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002454 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002455
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002456 def test_dump_privatekey_invalid_passphrase_type(self):
2457 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002458 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2459 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002460 """
2461 key = PKey()
2462 key.generate_key(TYPE_RSA, 512)
2463 self.assertRaises(
2464 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002465 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002466
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002467 def test_dump_privatekey_invalid_filetype(self):
2468 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002469 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2470 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002471 """
2472 key = PKey()
2473 key.generate_key(TYPE_RSA, 512)
2474 self.assertRaises(ValueError, dump_privatekey, 100, key)
2475
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002476 def test_load_privatekey_passphraseCallbackLength(self):
2477 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002478 :py:obj:`crypto.load_privatekey` should raise an error when the
2479 passphrase provided by the callback is too long, not silently truncate
2480 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002481 """
2482 def cb(ignored):
2483 return "a" * 1025
2484
Alex Gaynor791212d2015-09-05 15:46:08 -04002485 with pytest.raises(ValueError):
2486 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002487
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002488 def test_dump_privatekey_passphrase(self):
2489 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002490 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2491 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002492 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002493 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002494 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002495 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2496 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002497 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2498 self.assertTrue(isinstance(loadedKey, PKeyType))
2499 self.assertEqual(loadedKey.type(), key.type())
2500 self.assertEqual(loadedKey.bits(), key.bits())
2501
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002502 def test_dump_privatekey_passphraseWrongType(self):
2503 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002504 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2505 a passphrase with a private key encoded in a format, that doesn't
2506 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002507 """
2508 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002509 with pytest.raises(ValueError):
2510 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002511
Rick Dean5b7b6372009-04-01 11:34:06 -05002512 def test_dump_certificate(self):
2513 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002514 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002515 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002516 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002517 cert = load_certificate(FILETYPE_PEM, pemData)
2518 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2519 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2520 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002521 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002522 self.assertEqual(dumped_der, good_der)
2523 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2524 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2525 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2526 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002527 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002528 self.assertEqual(dumped_text, good_text)
2529
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002530 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002531 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002532 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002533 """
2534 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002535 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002536 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2537 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002538
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002539 def test_dump_privatekey_asn1(self):
2540 """
2541 :py:obj:`dump_privatekey` writes a DER
2542 """
2543 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2544 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2545
Rick Dean5b7b6372009-04-01 11:34:06 -05002546 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002547 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002548 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002549 self.assertEqual(dumped_der, good_der)
2550 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2551 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2552 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002553
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002554 def test_dump_privatekey_text(self):
2555 """
2556 :py:obj:`dump_privatekey` writes a text
2557 """
2558 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2559 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2560
Rick Dean5b7b6372009-04-01 11:34:06 -05002561 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002562 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002563 self.assertEqual(dumped_text, good_text)
2564
2565 def test_dump_certificate_request(self):
2566 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002567 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002568 """
Alex Gaynor31287502015-09-05 16:11:27 -04002569 req = load_certificate_request(
2570 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002571 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2572 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2573 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002574 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002575 self.assertEqual(dumped_der, good_der)
2576 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2577 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2578 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2579 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002580 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002581 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002582 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002583
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002584 def test_dump_privatekey_passphraseCallback(self):
2585 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002586 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2587 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002588 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002589 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002590 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002591
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002592 def cb(writing):
2593 called.append(writing)
2594 return passphrase
2595 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002596 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2597 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002598 self.assertEqual(called, [True])
2599 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2600 self.assertTrue(isinstance(loadedKey, PKeyType))
2601 self.assertEqual(loadedKey.type(), key.type())
2602 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002603
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002604 def test_dump_privatekey_passphrase_exception(self):
2605 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002606 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002607 by the passphrase callback.
2608 """
2609 def cb(ignored):
2610 raise ArithmeticError
2611
2612 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002613 with pytest.raises(ArithmeticError):
2614 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002615
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002616 def test_dump_privatekey_passphraseCallbackLength(self):
2617 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002618 :py:obj:`crypto.dump_privatekey` should raise an error when the
2619 passphrase provided by the callback is too long, not silently truncate
2620 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002621 """
2622 def cb(ignored):
2623 return "a" * 1025
2624
2625 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002626 with pytest.raises(ValueError):
2627 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002628
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002629 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002630 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002631 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2632 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002633 """
2634 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2635 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2636
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002637 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002638 """
2639 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2640 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2641 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002642 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2643 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2644
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002645 def test_load_pkcs7_data_invalid(self):
2646 """
2647 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2648 :py:obj:`Error` is raised.
2649 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002650 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002651
2652
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002653class LoadCertificateTests(TestCase):
2654 """
2655 Tests for :py:obj:`load_certificate_request`.
2656 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002657
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002658 def test_badFileType(self):
2659 """
2660 If the file type passed to :py:obj:`load_certificate_request` is
2661 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2662 :py:class:`ValueError` is raised.
2663 """
2664 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2665
2666
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002667class PKCS7Tests(TestCase):
2668 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002669 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002670 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002671
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002672 def test_type(self):
2673 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002674 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002675 """
2676 self.assertTrue(isinstance(PKCS7Type, type))
2677 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2678
2679 # XXX This doesn't currently work.
2680 # self.assertIdentical(PKCS7, PKCS7Type)
2681
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002682 # XXX Opposite results for all these following methods
2683
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002684 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002685 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002686 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2687 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002688 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002689 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2690 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2691
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002692 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002693 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002694 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2695 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002696 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002697 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2698 self.assertTrue(pkcs7.type_is_signed())
2699
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002700 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002701 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002702 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2703 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002704 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002705 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2706 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2707
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002708 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002709 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002710 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2711 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002712 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002713 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2714 self.assertFalse(pkcs7.type_is_enveloped())
2715
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002716 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002717 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002718 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2719 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002720 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002721 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2722 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2723
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002724 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002725 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002726 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2727 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002728 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002729 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2730 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2731
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002732 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002733 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002734 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2735 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002736 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002737 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2738 self.assertFalse(pkcs7.type_is_data())
2739
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002740 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002741 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002742 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2743 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002744 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002745 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2746 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2747
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002748 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002749 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002750 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2751 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002752 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002753 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2754 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2755
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002756 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002757 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002758 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2759 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002760 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002761 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002762 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002763
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002764 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002765 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002766 If an attribute other than one of the methods tested here is accessed
2767 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2768 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002769 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002770 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2771 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2772
2773
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002774class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002775 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002776 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002777 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002778
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002779 def signable(self):
2780 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002781 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002782 """
2783 return NetscapeSPKI()
2784
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002785 def test_type(self):
2786 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002787 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2788 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002789 """
2790 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2791 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2792
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002793 def test_construction(self):
2794 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002795 :py:obj:`NetscapeSPKI` returns an instance of
2796 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002797 """
2798 nspki = NetscapeSPKI()
2799 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2800
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002801 def test_invalid_attribute(self):
2802 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002803 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2804 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002805 """
2806 nspki = NetscapeSPKI()
2807 self.assertRaises(AttributeError, lambda: nspki.foo)
2808
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002809 def test_b64_encode(self):
2810 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002811 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2812 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002813 """
2814 nspki = NetscapeSPKI()
2815 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002816 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002817
2818
Rick Dean536ba022009-07-24 23:57:27 -05002819class RevokedTests(TestCase):
2820 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002821 Tests for :py:obj:`OpenSSL.crypto.Revoked`
Rick Dean536ba022009-07-24 23:57:27 -05002822 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002823
Rick Dean536ba022009-07-24 23:57:27 -05002824 def test_construction(self):
2825 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002826 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002827 that it is empty.
2828 """
2829 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002830 self.assertTrue(isinstance(revoked, Revoked))
2831 self.assertEquals(type(revoked), Revoked)
2832 self.assertEquals(revoked.get_serial(), b('00'))
2833 self.assertEquals(revoked.get_rev_date(), None)
2834 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05002835
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002836 def test_construction_wrong_args(self):
2837 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002838 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
2839 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002840 """
2841 self.assertRaises(TypeError, Revoked, None)
2842 self.assertRaises(TypeError, Revoked, 1)
2843 self.assertRaises(TypeError, Revoked, "foo")
2844
Rick Dean536ba022009-07-24 23:57:27 -05002845 def test_serial(self):
2846 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002847 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002848 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002849 with grace.
2850 """
2851 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002852 ret = revoked.set_serial(b('10b'))
2853 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002854 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002855 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05002856
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002857 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05002858 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002859 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05002860
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002861 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05002862 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002863 self.assertRaises(TypeError, revoked.get_serial, 1)
2864 self.assertRaises(TypeError, revoked.get_serial, None)
2865 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05002866
Rick Dean536ba022009-07-24 23:57:27 -05002867 def test_date(self):
2868 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002869 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002870 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002871 with grace.
2872 """
2873 revoked = Revoked()
2874 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002875 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05002876
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002877 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002878 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002879 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002880 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002881 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05002882
Rick Dean6385faf2009-07-26 00:07:47 -05002883 def test_reason(self):
2884 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002885 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002886 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05002887 as "set". Likewise, each reason of all_reasons() must work.
2888 """
2889 revoked = Revoked()
2890 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002891 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05002892 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002893 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05002894 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002895 self.assertEquals(
2896 reason.lower().replace(b(' '), b('')),
2897 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002898 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05002899
2900 revoked.set_reason(None)
2901 self.assertEqual(revoked.get_reason(), None)
2902
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002903 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05002904 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002905 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002906 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002907 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05002908 """
2909 revoked = Revoked()
2910 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04002911 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05002912
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002913 def test_get_reason_wrong_arguments(self):
2914 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002915 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
2916 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002917 """
2918 revoked = Revoked()
2919 self.assertRaises(TypeError, revoked.get_reason, None)
2920 self.assertRaises(TypeError, revoked.get_reason, 1)
2921 self.assertRaises(TypeError, revoked.get_reason, "foo")
2922
2923
Rick Dean536ba022009-07-24 23:57:27 -05002924class CRLTests(TestCase):
2925 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002926 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05002927 """
2928 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2929 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2930
2931 def test_construction(self):
2932 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002933 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002934 that it is empty
2935 """
2936 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04002937 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05002938 self.assertEqual(crl.get_revoked(), None)
2939
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05002940 def test_construction_wrong_args(self):
2941 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002942 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
2943 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05002944 """
2945 self.assertRaises(TypeError, CRL, 1)
2946 self.assertRaises(TypeError, CRL, "")
2947 self.assertRaises(TypeError, CRL, None)
2948
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002949 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05002950 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002951 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05002952 """
2953 crl = CRL()
2954 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002955 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002956 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002957 revoked.set_serial(b('3ab'))
2958 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05002959 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002960 return crl
Rick Dean536ba022009-07-24 23:57:27 -05002961
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002962 def test_export_pem(self):
2963 """
2964 If not passed a format, ``CRL.export`` returns a "PEM" format string
2965 representing a serial number, a revoked reason, and certificate issuer
2966 information.
2967 """
2968 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05002969 # PEM format
2970 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002971 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002972
2973 # These magic values are based on the way the CRL above was constructed
2974 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002975 text.index(b('Serial Number: 03AB'))
2976 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002977 text.index(
2978 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
2979 )
2980
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002981 def test_export_der(self):
2982 """
2983 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
2984 "DER" format string representing a serial number, a revoked reason, and
2985 certificate issuer information.
2986 """
2987 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05002988
2989 # DER format
2990 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002991 text = _runopenssl(
2992 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
2993 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002994 text.index(b('Serial Number: 03AB'))
2995 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002996 text.index(
2997 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
2998 )
2999
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003000 def test_export_text(self):
3001 """
3002 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3003 text format string like the one produced by the openssl command line
3004 tool.
3005 """
3006 crl = self._get_crl()
3007
3008 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3009 text = _runopenssl(
3010 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3011 )
Rick Dean536ba022009-07-24 23:57:27 -05003012
3013 # text format
3014 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3015 self.assertEqual(text, dumped_text)
3016
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003017 def test_export_custom_digest(self):
3018 """
3019 If passed the name of a digest function, ``CRL.export`` uses a
3020 signature algorithm based on that digest function.
3021 """
3022 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003023 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003024 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3025 text.index(b('Signature Algorithm: sha1'))
3026
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003027 def test_export_md5_digest(self):
3028 """
3029 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3030 not emit a deprecation warning.
3031 """
3032 crl = self._get_crl()
3033 with catch_warnings(record=True) as catcher:
3034 simplefilter("always")
3035 self.assertEqual(0, len(catcher))
3036 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3037 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3038 text.index(b('Signature Algorithm: md5'))
3039
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003040 def test_export_default_digest(self):
3041 """
3042 If not passed the name of a digest function, ``CRL.export`` uses a
3043 signature algorithm based on MD5 and emits a deprecation warning.
3044 """
3045 crl = self._get_crl()
3046 with catch_warnings(record=True) as catcher:
3047 simplefilter("always")
3048 dumped_crl = crl.export(self.cert, self.pkey)
3049 self.assertEqual(
3050 "The default message digest (md5) is deprecated. "
3051 "Pass the name of a message digest explicitly.",
3052 str(catcher[0].message),
3053 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003054 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3055 text.index(b('Signature Algorithm: md5'))
3056
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003057 def test_export_invalid(self):
3058 """
3059 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003060 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003061 """
3062 crl = CRL()
3063 self.assertRaises(Error, crl.export, X509(), PKey())
3064
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003065 def test_add_revoked_keyword(self):
3066 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003067 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003068 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003069 """
3070 crl = CRL()
3071 revoked = Revoked()
3072 crl.add_revoked(revoked=revoked)
3073 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3074
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003075 def test_export_wrong_args(self):
3076 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003077 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003078 four arguments, or with arguments other than the certificate,
3079 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003080 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003081 """
3082 crl = CRL()
3083 self.assertRaises(TypeError, crl.export)
3084 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003085 with pytest.raises(TypeError):
3086 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3087 with pytest.raises(TypeError):
3088 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3089 with pytest.raises(TypeError):
3090 crl.export(self.cert, None, FILETYPE_PEM, 10)
3091 with pytest.raises(TypeError):
3092 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003093 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3094
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003095 def test_export_unknown_filetype(self):
3096 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003097 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003098 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3099 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003100 """
3101 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003102 with pytest.raises(ValueError):
3103 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003104
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003105 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003106 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003107 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003108 in a :py:obj:`ValueError` being raised.
3109 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003110 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003111 self.assertRaises(
3112 ValueError,
3113 crl.export,
3114 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3115 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003116
Rick Dean536ba022009-07-24 23:57:27 -05003117 def test_get_revoked(self):
3118 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003119 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003120 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3121 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003122 """
3123 crl = CRL()
3124
3125 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003126 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003127 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003128 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003129 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003130 revoked.set_serial(b('100'))
3131 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003132 crl.add_revoked(revoked)
3133
3134 revs = crl.get_revoked()
3135 self.assertEqual(len(revs), 2)
3136 self.assertEqual(type(revs[0]), Revoked)
3137 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003138 self.assertEqual(revs[0].get_serial(), b('03AB'))
3139 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003140 self.assertEqual(revs[0].get_rev_date(), now)
3141 self.assertEqual(revs[1].get_rev_date(), now)
3142
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003143 def test_get_revoked_wrong_args(self):
3144 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003145 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3146 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003147 """
3148 crl = CRL()
3149 self.assertRaises(TypeError, crl.get_revoked, None)
3150 self.assertRaises(TypeError, crl.get_revoked, 1)
3151 self.assertRaises(TypeError, crl.get_revoked, "")
3152 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3153
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003154 def test_add_revoked_wrong_args(self):
3155 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003156 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3157 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003158 """
3159 crl = CRL()
3160 self.assertRaises(TypeError, crl.add_revoked)
3161 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3162 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3163
Rick Dean536ba022009-07-24 23:57:27 -05003164 def test_load_crl(self):
3165 """
3166 Load a known CRL and inspect its revocations. Both
3167 PEM and DER formats are loaded.
3168 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003169 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003170 revs = crl.get_revoked()
3171 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003172 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003173 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003174 self.assertEqual(revs[1].get_serial(), b('0100'))
3175 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003176
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003177 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003178 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003179 revs = crl.get_revoked()
3180 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003181 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003182 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003183 self.assertEqual(revs[1].get_serial(), b('0100'))
3184 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003185
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003186 def test_load_crl_wrong_args(self):
3187 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003188 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3189 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003190 """
3191 self.assertRaises(TypeError, load_crl)
3192 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3193 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3194
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003195 def test_load_crl_bad_filetype(self):
3196 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003197 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3198 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003199 """
3200 self.assertRaises(ValueError, load_crl, 100, crlData)
3201
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003202 def test_load_crl_bad_data(self):
3203 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003204 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3205 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003206 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003207 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003208
Dominic Chenf05b2122015-10-13 16:32:35 +00003209 def test_dump_crl(self):
3210 """
3211 The dumped CRL matches the original input.
3212 """
3213 crl = load_crl(FILETYPE_PEM, crlData)
3214 buf = dump_crl(FILETYPE_PEM, crl)
3215 assert buf == crlData
3216
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003217
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003218class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003219 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003220 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003221 """
3222 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3223 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003224 intermediate_server_cert = load_certificate(
3225 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003226
3227 def test_valid(self):
3228 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003229 :py:obj:`verify_certificate` returns ``None`` when called with a
3230 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003231 """
3232 store = X509Store()
3233 store.add_cert(self.root_cert)
3234 store.add_cert(self.intermediate_cert)
3235 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003236 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003237
3238 def test_reuse(self):
3239 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003240 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003241 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003242 """
3243 store = X509Store()
3244 store.add_cert(self.root_cert)
3245 store.add_cert(self.intermediate_cert)
3246 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003247 self.assertEqual(store_ctx.verify_certificate(), None)
3248 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003249
3250 def test_trusted_self_signed(self):
3251 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003252 :py:obj:`verify_certificate` returns ``None`` when called with a
3253 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003254 """
3255 store = X509Store()
3256 store.add_cert(self.root_cert)
3257 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003258 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003259
3260 def test_untrusted_self_signed(self):
3261 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003262 :py:obj:`verify_certificate` raises error when a self-signed
3263 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003264 """
3265 store = X509Store()
3266 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003267 with pytest.raises(X509StoreContextError) as exc:
3268 store_ctx.verify_certificate()
3269
3270 assert exc.value.args[0][2] == 'self signed certificate'
3271 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003272
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003273 def test_invalid_chain_no_root(self):
3274 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003275 :py:obj:`verify_certificate` raises error when a root certificate is
3276 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003277 """
3278 store = X509Store()
3279 store.add_cert(self.intermediate_cert)
3280 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003281
3282 with pytest.raises(X509StoreContextError) as exc:
3283 store_ctx.verify_certificate()
3284
3285 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3286 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003287
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003288 def test_invalid_chain_no_intermediate(self):
3289 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003290 :py:obj:`verify_certificate` raises error when an intermediate
3291 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003292 """
3293 store = X509Store()
3294 store.add_cert(self.root_cert)
3295 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003296
Alex Gaynor85b49702015-09-05 16:30:59 -04003297 with pytest.raises(X509StoreContextError) as exc:
3298 store_ctx.verify_certificate()
3299
3300 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3301 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003302
Stephen Holsapple46a09252015-02-12 14:45:43 -08003303 def test_modification_pre_verify(self):
3304 """
3305 :py:obj:`verify_certificate` can use a store context modified after
3306 instantiation.
3307 """
3308 store_bad = X509Store()
3309 store_bad.add_cert(self.intermediate_cert)
3310 store_good = X509Store()
3311 store_good.add_cert(self.root_cert)
3312 store_good.add_cert(self.intermediate_cert)
3313 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003314
3315 with pytest.raises(X509StoreContextError) as exc:
3316 store_ctx.verify_certificate()
3317
3318 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3319 assert exc.value.certificate.get_subject().CN == 'intermediate'
3320
Stephen Holsapple46a09252015-02-12 14:45:43 -08003321 store_ctx.set_store(store_good)
3322 self.assertEqual(store_ctx.verify_certificate(), None)
3323
3324
James Yonan7c2e5d32010-02-27 05:45:50 -07003325class SignVerifyTests(TestCase):
3326 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003327 Tests for :py:obj:`OpenSSL.crypto.sign` and
3328 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003329 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003330
James Yonan7c2e5d32010-02-27 05:45:50 -07003331 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003332 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003333 :py:obj:`sign` generates a cryptographic signature which
3334 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003335 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003336 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003337 "It was a bright cold day in April, and the clocks were striking "
3338 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3339 "effort to escape the vile wind, slipped quickly through the "
3340 "glass doors of Victory Mansions, though not quickly enough to "
3341 "prevent a swirl of gritty dust from entering along with him.")
3342
3343 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003344 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003345 # verify the content with this cert
3346 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3347 # certificate unrelated to priv_key, used to trigger an error
3348 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003349
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003350 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003351 sig = sign(priv_key, content, digest)
3352
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003353 # Verify the signature of content, will throw an exception if
3354 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003355 verify(good_cert, sig, content, digest)
3356
3357 # This should fail because the certificate doesn't match the
3358 # private key that was used to sign the content.
3359 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3360
3361 # This should fail because we've "tainted" the content after
3362 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003363 self.assertRaises(
3364 Error, verify,
3365 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003366
3367 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003368 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003369 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003370 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003371 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003372
Abraham Martinc5484ba2015-03-25 15:33:05 +00003373 def test_sign_verify_with_text(self):
3374 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003375 :py:obj:`sign` generates a cryptographic signature which
3376 :py:obj:`verify` can check. Deprecation warnings raised because using
3377 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003378 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003379 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003380 b"It was a bright cold day in April, and the clocks were striking "
3381 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3382 b"effort to escape the vile wind, slipped quickly through the "
3383 b"glass doors of Victory Mansions, though not quickly enough to "
3384 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003385 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003386
3387 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3388 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3389 for digest in ['md5', 'sha1']:
3390 with catch_warnings(record=True) as w:
3391 simplefilter("always")
3392 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003393
3394 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003395 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003396 WARNING_TYPE_EXPECTED
3397 ),
3398 str(w[-1].message)
3399 )
3400 self.assertIs(w[-1].category, DeprecationWarning)
3401
Abraham Martinc5484ba2015-03-25 15:33:05 +00003402 with catch_warnings(record=True) as w:
3403 simplefilter("always")
3404 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003405
3406 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003407 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003408 WARNING_TYPE_EXPECTED
3409 ),
3410 str(w[-1].message)
3411 )
3412 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003413
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003414 def test_sign_nulls(self):
3415 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003416 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003417 """
3418 content = b("Watch out! \0 Did you see it?")
3419 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3420 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3421 sig = sign(priv_key, content, "sha1")
3422 verify(good_cert, sig, content, "sha1")
3423
3424
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003425class EllipticCurveTests(TestCase):
3426 """
3427 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3428 :py:obj:`get_elliptic_curves`.
3429 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003430
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003431 def test_set(self):
3432 """
3433 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3434 """
3435 self.assertIsInstance(get_elliptic_curves(), set)
3436
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003437 def test_some_curves(self):
3438 """
3439 If :py:mod:`cryptography` has elliptic curve support then the set
3440 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3441 it.
3442
3443 There could be an OpenSSL that violates this assumption. If so, this
3444 test will fail and we'll find out.
3445 """
3446 curves = get_elliptic_curves()
3447 if lib.Cryptography_HAS_EC:
3448 self.assertTrue(curves)
3449 else:
3450 self.assertFalse(curves)
3451
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003452 def test_a_curve(self):
3453 """
3454 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3455 supported curve.
3456 """
3457 curves = get_elliptic_curves()
3458 if curves:
3459 curve = next(iter(curves))
3460 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3461 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003462 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003463
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003464 def test_not_a_curve(self):
3465 """
3466 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3467 with a name which does not identify a supported curve.
3468 """
3469 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003470 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003471
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003472 def test_repr(self):
3473 """
3474 The string representation of a curve object includes simply states the
3475 object is a curve and what its name is.
3476 """
3477 curves = get_elliptic_curves()
3478 if curves:
3479 curve = next(iter(curves))
3480 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3481
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003482 def test_to_EC_KEY(self):
3483 """
3484 The curve object can export a version of itself as an EC_KEY* via the
3485 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3486 """
3487 curves = get_elliptic_curves()
3488 if curves:
3489 curve = next(iter(curves))
3490 # It's not easy to assert anything about this object. However, see
3491 # leakcheck/crypto.py for a test that demonstrates it at least does
3492 # not leak memory.
3493 curve._to_EC_KEY()
3494
3495
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003496class EllipticCurveFactory(object):
3497 """
3498 A helper to get the names of two curves.
3499 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003500
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003501 def __init__(self):
3502 curves = iter(get_elliptic_curves())
3503 try:
3504 self.curve_name = next(curves).name
3505 self.another_curve_name = next(curves).name
3506 except StopIteration:
3507 self.curve_name = self.another_curve_name = None
3508
3509
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003510class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3511 """
3512 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3513 """
3514 curve_factory = EllipticCurveFactory()
3515
3516 if curve_factory.curve_name is None:
3517 skip = "There are no curves available there can be no curve objects."
3518
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003519 def anInstance(self):
3520 """
3521 Get the curve object for an arbitrary curve supported by the system.
3522 """
3523 return get_elliptic_curve(self.curve_factory.curve_name)
3524
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003525 def anotherInstance(self):
3526 """
3527 Get the curve object for an arbitrary curve supported by the system -
3528 but not the one returned by C{anInstance}.
3529 """
3530 return get_elliptic_curve(self.curve_factory.another_curve_name)
3531
3532
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003533class EllipticCurveHashTests(TestCase):
3534 """
3535 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3536 as an item in a :py:type:`dict` or :py:type:`set`).
3537 """
3538 curve_factory = EllipticCurveFactory()
3539
3540 if curve_factory.curve_name is None:
3541 skip = "There are no curves available there can be no curve objects."
3542
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003543 def test_contains(self):
3544 """
3545 The ``in`` operator reports that a :py:type:`set` containing a curve
3546 does contain that curve.
3547 """
3548 curve = get_elliptic_curve(self.curve_factory.curve_name)
3549 curves = set([curve])
3550 self.assertIn(curve, curves)
3551
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003552 def test_does_not_contain(self):
3553 """
3554 The ``in`` operator reports that a :py:type:`set` not containing a
3555 curve does not contain that curve.
3556 """
3557 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003558 curves = set([
3559 get_elliptic_curve(self.curve_factory.another_curve_name)
3560 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003561 self.assertNotIn(curve, curves)
3562
3563
Rick Dean5b7b6372009-04-01 11:34:06 -05003564if __name__ == '__main__':
3565 main()