blob: 6c8f1799339422860c42a7c86765c84277ee9380 [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
Rick Dean536ba022009-07-24 23:57:27 -050034from OpenSSL.crypto import CRL, Revoked, 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)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040038from OpenSSL.test.util import (
39 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
40)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040041from OpenSSL._util import native, lib
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040042
Alex Gaynoraceb3e22015-09-05 12:00:22 -040043
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040044def normalize_certificate_pem(pem):
45 return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
46
47
48def normalize_privatekey_pem(pem):
49 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
50
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040051
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050052GOOD_CIPHER = "blowfish"
53BAD_CIPHER = "zippers"
54
55GOOD_DIGEST = "MD5"
56BAD_DIGEST = "monkeys"
57
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040058root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050059MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
60BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
61ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
62NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
63MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
64ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
65urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
662xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
671dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
68FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
69VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
70BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
71b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
72AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
73hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
74w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
75-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040076""")
Rick Dean94e46fd2009-07-18 14:51:24 -050077
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040078root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050079MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
80jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
813claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
82AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
83yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
846JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
85BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
86u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
87PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
88I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
89ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
906AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
91cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
92-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040093""")
Rick Dean94e46fd2009-07-18 14:51:24 -050094
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070095intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
96MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
97WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
98DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
99ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
100dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
101MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
102AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
103FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
10421H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
105AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
106QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1079n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1089mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
109-----END CERTIFICATE-----
110""")
111
112intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
113MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
114ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
115qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
116AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
117rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
118147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
119+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
120wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
121sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
12252vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
123DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
124/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
125NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
126-----END RSA PRIVATE KEY-----
127""")
128
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400129server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500130MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
131BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
132VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
133NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
134gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
135lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
136b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
137lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
138gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
139dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1402mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
141uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
142-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400143""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500144
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400145server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500146MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
147U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
148SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
149AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
150j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
151j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
152Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
153msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
154FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1554e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1561sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
157NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
158r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
159-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400160"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500161
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700162intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
163MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
164ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
165CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
166biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
167BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
168CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
169biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
170iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
171+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
172biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
173UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1743bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
175x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
176-----END CERTIFICATE-----
177""")
178
179intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
180MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
181SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1828Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
183AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1845ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
185d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
186z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
187dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
188EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
189X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
1909UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
191ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
192nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
193-----END RSA PRIVATE KEY-----
194""")
195
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400196client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500197MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
198BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
199VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
200ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
201MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
202rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
203iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
204oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2050fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
206Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2079Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
208PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
209-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400210""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500211
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400212client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500213MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
214btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
215eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
216AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
217zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
218h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
219V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
220TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
221dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
222D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
223si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
224JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
225f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
226-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400227"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400228
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400229cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400230MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
231BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
232ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
233NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
234MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
235ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
236urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2372xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2381dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
239FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
240VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
241BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
242b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
243AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
244hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
245w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
246-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400247""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400248
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400249cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
250-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400251MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
252jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2533claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
254AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
255yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2566JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
257BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
258u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
259PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
260I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
261ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2626AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
263cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
264-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400265"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400266
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400267cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
268MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
269EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
270ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
271BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
272E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
273xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
274gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
275Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
276oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
277-----END CERTIFICATE REQUEST-----
278""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500279
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400280encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400281Proc-Type: 4,ENCRYPTED
282DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400283
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400284SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
285a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2868+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
287mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
288+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
289fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
290tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
291rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
292gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
293o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
2947SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
295MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
29611n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
297-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400298""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400299
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400300encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400301
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400302# Some PKCS#7 stuff. Generated with the openssl command line:
303#
304# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
305#
306# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400307pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400308-----BEGIN PKCS7-----
309MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
310BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
311A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
312MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
313cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
314A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
315HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
316SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
317zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
318LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
319A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
32065w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
321Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
322Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
323bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
324VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
325/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
326Ho4EzbYCOaEAMQA=
327-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400328""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400329
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700330pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700331MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
332BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
333A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
334MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
335cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
336A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
337HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
338SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
339zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
340LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
341A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
34265w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
343Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
344Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
345bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
346VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
347/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
348Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700349""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700350
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400351crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500352-----BEGIN X509 CRL-----
353MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
354SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
355D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
356MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
357MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3584dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3590yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
360vrzEeLDRiiPl92dyyWmu
361-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400362""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400363
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400364
365# A broken RSA private key which can be used to test the error path through
366# PKey.check.
367inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
368MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
3695kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
370OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
371zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
372nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
373HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
374oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
375-----END RSA PRIVATE KEY-----
376""")
377
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400378# certificate with NULL bytes in subjectAltName and common name
379
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400380nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400381MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
382DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
383eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
384RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
385ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
386NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
387DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
388ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
389ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
390hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
391BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
392pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
393vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
394KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
395oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
39608LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
397HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
398BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
399Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
400bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
401AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
402i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
403HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
404kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
405VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
406RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
407-----END CERTIFICATE-----""")
408
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400409
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400410class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400411 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900412 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400413 """
414
415 def setUp(self):
416 """
417 Create a new private key and start a certificate request (for a test
418 method to finish in one way or another).
419 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800420 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400421 # Basic setup stuff to generate a certificate
422 self.pkey = PKey()
423 self.pkey.generate_key(TYPE_RSA, 384)
424 self.req = X509Req()
425 self.req.set_pubkey(self.pkey)
426 # Authority good you have.
427 self.req.get_subject().commonName = "Yoda root CA"
428 self.x509 = X509()
429 self.subject = self.x509.get_subject()
430 self.subject.commonName = self.req.get_subject().commonName
431 self.x509.set_issuer(self.subject)
432 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400433 now = datetime.now()
434 expire = datetime.now() + timedelta(days=100)
435 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
436 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400437
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800438 def tearDown(self):
439 """
440 Forget all of the pyOpenSSL objects so they can be garbage collected,
441 their memory released, and not interfere with the leak detection code.
442 """
443 self.pkey = self.req = self.x509 = self.subject = None
444 super(X509ExtTests, self).tearDown()
445
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400446 def test_str(self):
447 """
Alex Gaynor31287502015-09-05 16:11:27 -0400448 The string representation of :py:class:`X509Extension` instances as
449 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400450 """
451 # This isn't necessarily the best string representation. Perhaps it
452 # will be changed/improved in the future.
453 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400454 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400455 'CA:FALSE')
456
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400457 def test_type(self):
458 """
Alex Gaynor31287502015-09-05 16:11:27 -0400459 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
460 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400461 """
462 self.assertIdentical(X509Extension, X509ExtensionType)
463 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400464 X509Extension,
465 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400466
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500467 def test_construction(self):
468 """
Alex Gaynor31287502015-09-05 16:11:27 -0400469 :py:class:`X509Extension` accepts an extension type name, a critical
470 flag, and an extension value and returns an
471 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500472 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400473 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500474 self.assertTrue(
475 isinstance(basic, X509ExtensionType),
476 "%r is of type %r, should be %r" % (
477 basic, type(basic), X509ExtensionType))
478
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400479 comment = X509Extension(
480 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500481 self.assertTrue(
482 isinstance(comment, X509ExtensionType),
483 "%r is of type %r, should be %r" % (
484 comment, type(comment), X509ExtensionType))
485
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500486 def test_invalid_extension(self):
487 """
Alex Gaynor31287502015-09-05 16:11:27 -0400488 :py:class:`X509Extension` raises something if it is passed a bad
489 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500490 """
491 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400492 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500493 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400494 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500495
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500496 # Exercise a weird one (an extension which uses the r2i method). This
497 # exercises the codepath that requires a non-NULL ctx to be passed to
498 # X509V3_EXT_nconf. It can't work now because we provide no
499 # configuration database. It might be made to work in the future.
500 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400501 Error, X509Extension, b('proxyCertInfo'), True,
502 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500503
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500504 def test_get_critical(self):
505 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900506 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500507 extension's critical flag.
508 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400509 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500510 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400511 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500512 self.assertFalse(ext.get_critical())
513
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500514 def test_get_short_name(self):
515 """
Alex Gaynor31287502015-09-05 16:11:27 -0400516 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
517 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500518 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400519 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
520 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
521 ext = X509Extension(b('nsComment'), True, b('foo bar'))
522 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500523
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400524 def test_get_data(self):
525 """
Alex Gaynor31287502015-09-05 16:11:27 -0400526 :py:meth:`X509Extension.get_data` returns a string giving the data of
527 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400528 """
529 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
530 # Expect to get back the DER encoded form of CA:true.
531 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
532
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400533 def test_get_data_wrong_args(self):
534 """
Alex Gaynor31287502015-09-05 16:11:27 -0400535 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
536 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400537 """
538 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
539 self.assertRaises(TypeError, ext.get_data, None)
540 self.assertRaises(TypeError, ext.get_data, "foo")
541 self.assertRaises(TypeError, ext.get_data, 7)
542
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400543 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500544 """
Alex Gaynor31287502015-09-05 16:11:27 -0400545 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
546 provided for an extension which does not use it and is ignored in this
547 case.
Rick Dean47262da2009-07-08 16:17:17 -0500548 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400549 ext1 = X509Extension(
550 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400551 self.x509.add_extensions([ext1])
552 self.x509.sign(self.pkey, 'sha1')
553 # This is a little lame. Can we think of a better way?
554 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400555 self.assertTrue(b('X509v3 Basic Constraints:') in text)
556 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400557
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400558 def test_subject(self):
559 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900560 If an extension requires a subject, the :py:data:`subject` parameter to
561 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400562 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400563 ext3 = X509Extension(
564 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400565 self.x509.add_extensions([ext3])
566 self.x509.sign(self.pkey, 'sha1')
567 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400568 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400569
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400570 def test_missing_subject(self):
571 """
Alex Gaynor31287502015-09-05 16:11:27 -0400572 If an extension requires a subject and the :py:data:`subject` parameter
573 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400574 """
575 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400576 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400577
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400578 def test_invalid_subject(self):
579 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900580 If the :py:data:`subject` parameter is given a value which is not an
581 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400582 """
583 for badObj in [True, object(), "hello", [], self]:
584 self.assertRaises(
585 TypeError,
586 X509Extension,
587 'basicConstraints', False, 'CA:TRUE', subject=badObj)
588
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400589 def test_unused_issuer(self):
590 """
Alex Gaynor31287502015-09-05 16:11:27 -0400591 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
592 provided for an extension which does not use it and is ignored in this
593 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400594 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400595 ext1 = X509Extension(
596 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400597 self.x509.add_extensions([ext1])
598 self.x509.sign(self.pkey, 'sha1')
599 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400600 self.assertTrue(b('X509v3 Basic Constraints:') in text)
601 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400602
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400603 def test_issuer(self):
604 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800605 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900606 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400607 """
608 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400609 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400610 issuer=self.x509)
611 self.x509.add_extensions([ext2])
612 self.x509.sign(self.pkey, 'sha1')
613 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400614 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
615 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400616
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400617 def test_missing_issuer(self):
618 """
Alex Gaynor31287502015-09-05 16:11:27 -0400619 If an extension requires an issue and the :py:data:`issuer` parameter
620 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400621 """
622 self.assertRaises(
623 Error,
624 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400625 b('authorityKeyIdentifier'), False,
626 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400627
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400628 def test_invalid_issuer(self):
629 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900630 If the :py:data:`issuer` parameter is given a value which is not an
631 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400632 """
633 for badObj in [True, object(), "hello", [], self]:
634 self.assertRaises(
635 TypeError,
636 X509Extension,
637 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
638 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500639
640
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400641class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500642 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900643 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500644 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400645
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400646 def test_type(self):
647 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900648 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
649 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400650 """
651 self.assertIdentical(PKey, PKeyType)
652 self.assertConsistentType(PKey, 'PKey')
653
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500654 def test_construction(self):
655 """
Alex Gaynor31287502015-09-05 16:11:27 -0400656 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
657 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500658 """
659 self.assertRaises(TypeError, PKey, None)
660 key = PKey()
661 self.assertTrue(
662 isinstance(key, PKeyType),
663 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
664
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500665 def test_pregeneration(self):
666 """
Alex Gaynor31287502015-09-05 16:11:27 -0400667 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
668 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
669 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500670 """
671 key = PKey()
672 self.assertEqual(key.type(), 0)
673 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400674 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500675
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500676 def test_failedGeneration(self):
677 """
Alex Gaynor31287502015-09-05 16:11:27 -0400678 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
679 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
680 the second giving the number of bits to generate. If an invalid type
681 is specified or generation fails, :py:exc:`Error` is raised. If an
682 invalid number of bits is specified, :py:exc:`ValueError` or
683 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500684 """
685 key = PKey()
686 self.assertRaises(TypeError, key.generate_key)
687 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
688 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
689 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500690
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500691 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
692 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500693
694 # XXX RSA generation for small values of bits is fairly buggy in a wide
695 # range of OpenSSL versions. I need to figure out what the safe lower
696 # bound for a reasonable number of OpenSSL versions is and explicitly
697 # check for that in the wrapper. The failure behavior is typically an
698 # infinite loop inside OpenSSL.
699
700 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500701
702 # XXX DSA generation seems happy with any number of bits. The DSS
703 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
704 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500705 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500706 # So, it doesn't seem possible to make generate_key fail for
707 # TYPE_DSA with a bits argument which is at least an int.
708
709 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
710
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500711 def test_rsaGeneration(self):
712 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900713 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
714 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500715 """
716 bits = 128
717 key = PKey()
718 key.generate_key(TYPE_RSA, bits)
719 self.assertEqual(key.type(), TYPE_RSA)
720 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400721 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500722
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500723 def test_dsaGeneration(self):
724 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900725 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
726 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500727 """
728 # 512 is a magic number. The DSS (Digital Signature Standard)
729 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
730 # will silently promote any value below 512 to 512.
731 bits = 512
732 key = PKey()
733 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800734 # self.assertEqual(key.type(), TYPE_DSA)
735 # self.assertEqual(key.bits(), bits)
736 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500737
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500738 def test_regeneration(self):
739 """
Alex Gaynor31287502015-09-05 16:11:27 -0400740 :py:meth:`PKeyType.generate_key` can be called multiple times on the
741 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500742 """
743 key = PKey()
744 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400745 key.generate_key(type, bits)
746 self.assertEqual(key.type(), type)
747 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500748
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400749 def test_inconsistentKey(self):
750 """
Alex Gaynor31287502015-09-05 16:11:27 -0400751 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
752 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400753 """
754 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400755 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400756
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400757 def test_check_wrong_args(self):
758 """
Alex Gaynor31287502015-09-05 16:11:27 -0400759 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
760 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400761 """
762 self.assertRaises(TypeError, PKey().check, None)
763 self.assertRaises(TypeError, PKey().check, object())
764 self.assertRaises(TypeError, PKey().check, 1)
765
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400766 def test_check_public_key(self):
767 """
768 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
769 part of the key is available.
770 """
771 # A trick to get a public-only key
772 key = PKey()
773 key.generate_key(TYPE_RSA, 512)
774 cert = X509()
775 cert.set_pubkey(key)
776 pub = cert.get_pubkey()
777 self.assertRaises(TypeError, pub.check)
778
779
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400780class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500781 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900782 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500783 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400784
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500785 def _x509name(self, **attrs):
786 # XXX There's no other way to get a new X509Name yet.
787 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400788 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400789
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500790 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400791 def key(attr):
792 return attr[1]
793 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500794 for k, v in attrs:
795 setattr(name, k, v)
796 return name
797
Rick Deane15b1472009-07-09 15:53:42 -0500798 def test_type(self):
799 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900800 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500801 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400802 self.assertIdentical(X509Name, X509NameType)
803 self.assertEqual(X509NameType.__name__, 'X509Name')
804 self.assertTrue(isinstance(X509NameType, type))
805
Rick Deane15b1472009-07-09 15:53:42 -0500806 name = self._x509name()
807 self.assertTrue(
808 isinstance(name, X509NameType),
809 "%r is of type %r, should be %r" % (
810 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500811
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400812 def test_onlyStringAttributes(self):
813 """
Alex Gaynor31287502015-09-05 16:11:27 -0400814 Attempting to set a non-:py:data:`str` attribute name on an
815 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
816 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400817 """
818 name = self._x509name()
819 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400820 # rejected. Sorry, you're wrong. unicode is automatically converted
821 # to str outside of the control of X509Name, so there's no way to
822 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800823
Alex Gaynor31287502015-09-05 16:11:27 -0400824 # Also, this used to test str subclasses, but that test is less
825 # relevant now that the implementation is in Python instead of C. Also
826 # PyPy automatically converts str subclasses to str when they are
827 # passed to setattr, so we can't test it on PyPy. Apparently CPython
828 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400829 self.assertRaises(TypeError, setattr, name, None, "hello")
830 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400831
832 def test_setInvalidAttribute(self):
833 """
Alex Gaynor31287502015-09-05 16:11:27 -0400834 Attempting to set any attribute name on an :py:class:`X509NameType`
835 instance for which no corresponding NID is defined causes
836 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400837 """
838 name = self._x509name()
839 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
840
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500841 def test_attributes(self):
842 """
Alex Gaynor31287502015-09-05 16:11:27 -0400843 :py:class:`X509NameType` instances have attributes for each standard
844 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500845 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500846 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500847 name.commonName = "foo"
848 self.assertEqual(name.commonName, "foo")
849 self.assertEqual(name.CN, "foo")
850 name.CN = "baz"
851 self.assertEqual(name.commonName, "baz")
852 self.assertEqual(name.CN, "baz")
853 name.commonName = "bar"
854 self.assertEqual(name.commonName, "bar")
855 self.assertEqual(name.CN, "bar")
856 name.CN = "quux"
857 self.assertEqual(name.commonName, "quux")
858 self.assertEqual(name.CN, "quux")
859
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500860 def test_copy(self):
861 """
Alex Gaynor31287502015-09-05 16:11:27 -0400862 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
863 with all the same attributes as an existing :py:class:`X509NameType`
864 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500865 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500866 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500867
868 copy = X509Name(name)
869 self.assertEqual(copy.commonName, "foo")
870 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500871
872 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500873 copy.commonName = "baz"
874 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500875
876 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500877 name.emailAddress = "quux@example.com"
878 self.assertEqual(copy.emailAddress, "bar@example.com")
879
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500880 def test_repr(self):
881 """
Alex Gaynor31287502015-09-05 16:11:27 -0400882 :py:func:`repr` passed an :py:class:`X509NameType` instance should
883 return a string containing a description of the type and the NIDs which
884 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500885 """
886 name = self._x509name(commonName="foo", emailAddress="bar")
887 self.assertEqual(
888 repr(name),
889 "<X509Name object '/emailAddress=bar/CN=foo'>")
890
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500891 def test_comparison(self):
892 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900893 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500894 """
895 def _equality(a, b, assertTrue, assertFalse):
896 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
897 assertFalse(a != b)
898 assertTrue(b == a)
899 assertFalse(b != a)
900
901 def assertEqual(a, b):
902 _equality(a, b, self.assertTrue, self.assertFalse)
903
904 # Instances compare equal to themselves.
905 name = self._x509name()
906 assertEqual(name, name)
907
908 # Empty instances should compare equal to each other.
909 assertEqual(self._x509name(), self._x509name())
910
911 # Instances with equal NIDs should compare equal to each other.
912 assertEqual(self._x509name(commonName="foo"),
913 self._x509name(commonName="foo"))
914
915 # Instance with equal NIDs set using different aliases should compare
916 # equal to each other.
917 assertEqual(self._x509name(commonName="foo"),
918 self._x509name(CN="foo"))
919
920 # Instances with more than one NID with the same values should compare
921 # equal to each other.
922 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
923 self._x509name(commonName="foo", OU="bar"))
924
925 def assertNotEqual(a, b):
926 _equality(a, b, self.assertFalse, self.assertTrue)
927
928 # Instances with different values for the same NID should not compare
929 # equal to each other.
930 assertNotEqual(self._x509name(CN="foo"),
931 self._x509name(CN="bar"))
932
933 # Instances with different NIDs should not compare equal to each other.
934 assertNotEqual(self._x509name(CN="foo"),
935 self._x509name(OU="foo"))
936
937 def _inequality(a, b, assertTrue, assertFalse):
938 assertTrue(a < b)
939 assertTrue(a <= b)
940 assertTrue(b > a)
941 assertTrue(b >= a)
942 assertFalse(a > b)
943 assertFalse(a >= b)
944 assertFalse(b < a)
945 assertFalse(b <= a)
946
947 def assertLessThan(a, b):
948 _inequality(a, b, self.assertTrue, self.assertFalse)
949
950 # An X509Name with a NID with a value which sorts less than the value
951 # of the same NID on another X509Name compares less than the other
952 # X509Name.
953 assertLessThan(self._x509name(CN="abc"),
954 self._x509name(CN="def"))
955
956 def assertGreaterThan(a, b):
957 _inequality(a, b, self.assertFalse, self.assertTrue)
958
959 # An X509Name with a NID with a value which sorts greater than the
960 # value of the same NID on another X509Name compares greater than the
961 # other X509Name.
962 assertGreaterThan(self._x509name(CN="def"),
963 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500964
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400965 def test_hash(self):
966 """
Alex Gaynor31287502015-09-05 16:11:27 -0400967 :py:meth:`X509Name.hash` returns an integer hash based on the value of
968 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400969 """
970 a = self._x509name(CN="foo")
971 b = self._x509name(CN="foo")
972 self.assertEqual(a.hash(), b.hash())
973 a.CN = "bar"
974 self.assertNotEqual(a.hash(), b.hash())
975
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400976 def test_der(self):
977 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900978 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400979 """
980 a = self._x509name(CN="foo", C="US")
981 self.assertEqual(
982 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400983 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +0200984 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400985
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400986 def test_get_components(self):
987 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900988 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
989 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400990 giving the NIDs and associated values which make up the name.
991 """
992 a = self._x509name()
993 self.assertEqual(a.get_components(), [])
994 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400995 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400996 a.organizationalUnitName = "bar"
997 self.assertEqual(
998 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400999 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001000
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001001 def test_load_nul_byte_attribute(self):
1002 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001003 An :py:class:`OpenSSL.crypto.X509Name` from an
1004 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001005 NUL byte in the value of one of its attributes.
1006 """
1007 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1008 subject = cert.get_subject()
1009 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001010 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001011
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001012 def test_setAttributeFailure(self):
1013 """
1014 If the value of an attribute cannot be set for some reason then
1015 :py:class:`OpenSSL.crypto.Error` is raised.
1016 """
1017 name = self._x509name()
1018 # This value is too long
1019 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1020
1021
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001022class _PKeyInteractionTestsMixin:
1023 """
1024 Tests which involve another thing and a PKey.
1025 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001026
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001027 def signable(self):
1028 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001029 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1030 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001031 """
1032 raise NotImplementedError()
1033
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001034 def test_signWithUngenerated(self):
1035 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001036 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1037 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001038 """
1039 request = self.signable()
1040 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001041 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001042
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001043 def test_signWithPublicKey(self):
1044 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001045 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1046 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001047 """
1048 request = self.signable()
1049 key = PKey()
1050 key.generate_key(TYPE_RSA, 512)
1051 request.set_pubkey(key)
1052 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001053 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001054
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001055 def test_signWithUnknownDigest(self):
1056 """
Alex Gaynor31287502015-09-05 16:11:27 -04001057 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1058 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001059 """
1060 request = self.signable()
1061 key = PKey()
1062 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001063 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001064
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001065 def test_sign(self):
1066 """
Alex Gaynor31287502015-09-05 16:11:27 -04001067 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1068 valid digest function. :py:meth:`X509Req.verify` can be used to check
1069 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001070 """
1071 request = self.signable()
1072 key = PKey()
1073 key.generate_key(TYPE_RSA, 512)
1074 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001075 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001076 # If the type has a verify method, cover that too.
1077 if getattr(request, 'verify', None) is not None:
1078 pub = request.get_pubkey()
1079 self.assertTrue(request.verify(pub))
1080 # Make another key that won't verify.
1081 key = PKey()
1082 key.generate_key(TYPE_RSA, 512)
1083 self.assertRaises(Error, request.verify, key)
1084
1085
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001086class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001087 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001088 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001089 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001090
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001091 def signable(self):
1092 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001093 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001094 """
1095 return X509Req()
1096
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001097 def test_type(self):
1098 """
Alex Gaynor31287502015-09-05 16:11:27 -04001099 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1100 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001101 """
1102 self.assertIdentical(X509Req, X509ReqType)
1103 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001104
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001105 def test_construction(self):
1106 """
Alex Gaynor31287502015-09-05 16:11:27 -04001107 :py:obj:`X509Req` takes no arguments and returns an
1108 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001109 """
1110 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001111 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001112
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001113 def test_version(self):
1114 """
Alex Gaynor31287502015-09-05 16:11:27 -04001115 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1116 certificate request. :py:obj:`X509ReqType.get_version` returns the
1117 X.509 version of the certificate request. The initial value of the
1118 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001119 """
1120 request = X509Req()
1121 self.assertEqual(request.get_version(), 0)
1122 request.set_version(1)
1123 self.assertEqual(request.get_version(), 1)
1124 request.set_version(3)
1125 self.assertEqual(request.get_version(), 3)
1126
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001127 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001128 """
Alex Gaynor31287502015-09-05 16:11:27 -04001129 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1130 with the wrong number of arguments or with a non-:py:obj:`int`
1131 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1132 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001133 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001134 request = X509Req()
1135 self.assertRaises(TypeError, request.set_version)
1136 self.assertRaises(TypeError, request.set_version, "foo")
1137 self.assertRaises(TypeError, request.set_version, 1, 2)
1138 self.assertRaises(TypeError, request.get_version, None)
1139
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001140 def test_get_subject(self):
1141 """
Alex Gaynor31287502015-09-05 16:11:27 -04001142 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1143 subject of the request and which is valid even after the request object
1144 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001145 """
1146 request = X509Req()
1147 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001148 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001149 subject.commonName = "foo"
1150 self.assertEqual(request.get_subject().commonName, "foo")
1151 del request
1152 subject.commonName = "bar"
1153 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001154
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001155 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001156 """
Alex Gaynor31287502015-09-05 16:11:27 -04001157 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1158 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001159 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001160 request = X509Req()
1161 self.assertRaises(TypeError, request.get_subject, None)
1162
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001163 def test_add_extensions(self):
1164 """
Alex Gaynor31287502015-09-05 16:11:27 -04001165 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1166 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001167 """
1168 request = X509Req()
1169 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001170 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001171 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001172 self.assertEqual(len(exts), 1)
1173 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1174 self.assertEqual(exts[0].get_critical(), 1)
1175 self.assertEqual(exts[0].get_data(), b('0\x00'))
1176
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001177 def test_get_extensions(self):
1178 """
1179 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1180 extensions added to this X509 request.
1181 """
1182 request = X509Req()
1183 exts = request.get_extensions()
1184 self.assertEqual(exts, [])
1185 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001186 X509Extension(b('basicConstraints'), True, b('CA:true')),
1187 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001188 exts = request.get_extensions()
1189 self.assertEqual(len(exts), 2)
1190 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1191 self.assertEqual(exts[0].get_critical(), 1)
1192 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1193 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1194 self.assertEqual(exts[1].get_critical(), 0)
1195 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001196
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001197 def test_add_extensions_wrong_args(self):
1198 """
Alex Gaynor31287502015-09-05 16:11:27 -04001199 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1200 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1201 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1202 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001203 """
1204 request = X509Req()
1205 self.assertRaises(TypeError, request.add_extensions)
1206 self.assertRaises(TypeError, request.add_extensions, object())
1207 self.assertRaises(ValueError, request.add_extensions, [object()])
1208 self.assertRaises(TypeError, request.add_extensions, [], None)
1209
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001210 def test_verify_wrong_args(self):
1211 """
1212 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1213 arguments or more than one argument or if passed anything other than a
1214 :py:obj:`PKey` instance as its single argument.
1215 """
1216 request = X509Req()
1217 self.assertRaises(TypeError, request.verify)
1218 self.assertRaises(TypeError, request.verify, object())
1219 self.assertRaises(TypeError, request.verify, PKey(), object())
1220
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001221 def test_verify_uninitialized_key(self):
1222 """
Alex Gaynor31287502015-09-05 16:11:27 -04001223 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1224 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001225 """
1226 request = X509Req()
1227 pkey = PKey()
1228 self.assertRaises(Error, request.verify, pkey)
1229
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001230 def test_verify_wrong_key(self):
1231 """
Alex Gaynor31287502015-09-05 16:11:27 -04001232 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1233 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1234 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001235 """
1236 request = X509Req()
1237 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001238 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001239 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1240 self.assertRaises(Error, request.verify, another_pkey)
1241
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001242 def test_verify_success(self):
1243 """
1244 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001245 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1246 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001247 """
1248 request = X509Req()
1249 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001250 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001251 self.assertEqual(True, request.verify(pkey))
1252
1253
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001254class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001255 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001256 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001257 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001258 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001259
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001260 extpem = """
1261-----BEGIN CERTIFICATE-----
1262MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1263BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1264eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1265MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1266aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1267hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1268Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1269zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1270hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1271TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
127203HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1273MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1274b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1275MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1276uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1277WpOdIpB8KksUTCzV591Nr1wd
1278-----END CERTIFICATE-----
1279 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001280
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001281 def signable(self):
1282 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001283 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001284 """
1285 return X509()
1286
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001287 def test_type(self):
1288 """
Alex Gaynor31287502015-09-05 16:11:27 -04001289 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1290 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001291 """
1292 self.assertIdentical(X509, X509Type)
1293 self.assertConsistentType(X509, 'X509')
1294
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001295 def test_construction(self):
1296 """
Alex Gaynor31287502015-09-05 16:11:27 -04001297 :py:obj:`X509` takes no arguments and returns an instance of
1298 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001299 """
1300 certificate = X509()
1301 self.assertTrue(
1302 isinstance(certificate, X509Type),
1303 "%r is of type %r, should be %r" % (certificate,
1304 type(certificate),
1305 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001306 self.assertEqual(type(X509Type).__name__, 'type')
1307 self.assertEqual(type(certificate).__name__, 'X509')
1308 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001309 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001310
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001311 def test_get_version_wrong_args(self):
1312 """
Alex Gaynor31287502015-09-05 16:11:27 -04001313 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1314 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001315 """
1316 cert = X509()
1317 self.assertRaises(TypeError, cert.get_version, None)
1318
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001319 def test_set_version_wrong_args(self):
1320 """
Alex Gaynor31287502015-09-05 16:11:27 -04001321 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1322 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001323 """
1324 cert = X509()
1325 self.assertRaises(TypeError, cert.set_version)
1326 self.assertRaises(TypeError, cert.set_version, None)
1327 self.assertRaises(TypeError, cert.set_version, 1, None)
1328
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001329 def test_version(self):
1330 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001331 :py:obj:`X509.set_version` sets the certificate version number.
1332 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001333 """
1334 cert = X509()
1335 cert.set_version(1234)
1336 self.assertEquals(cert.get_version(), 1234)
1337
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001338 def test_get_serial_number_wrong_args(self):
1339 """
Alex Gaynor31287502015-09-05 16:11:27 -04001340 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1341 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001342 """
1343 cert = X509()
1344 self.assertRaises(TypeError, cert.get_serial_number, None)
1345
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001346 def test_serial_number(self):
1347 """
Alex Gaynor31287502015-09-05 16:11:27 -04001348 The serial number of an :py:obj:`X509Type` can be retrieved and
1349 modified with :py:obj:`X509Type.get_serial_number` and
1350 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001351 """
1352 certificate = X509()
1353 self.assertRaises(TypeError, certificate.set_serial_number)
1354 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1355 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1356 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1357 self.assertEqual(certificate.get_serial_number(), 0)
1358 certificate.set_serial_number(1)
1359 self.assertEqual(certificate.get_serial_number(), 1)
1360 certificate.set_serial_number(2 ** 32 + 1)
1361 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1362 certificate.set_serial_number(2 ** 64 + 1)
1363 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001364 certificate.set_serial_number(2 ** 128 + 1)
1365 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1366
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001367 def _setBoundTest(self, which):
1368 """
Alex Gaynor31287502015-09-05 16:11:27 -04001369 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1370 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1371 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001372 """
1373 certificate = X509()
1374 set = getattr(certificate, 'set_not' + which)
1375 get = getattr(certificate, 'get_not' + which)
1376
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001377 # Starts with no value.
1378 self.assertEqual(get(), None)
1379
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001380 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001381 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001382 set(when)
1383 self.assertEqual(get(), when)
1384
1385 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001386 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001387 set(when)
1388 self.assertEqual(get(), when)
1389
1390 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001391 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001392 set(when)
1393 self.assertEqual(get(), when)
1394
1395 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001396 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001397
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001398 # The wrong number of arguments results in a TypeError.
1399 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001400 with pytest.raises(TypeError):
1401 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001402 self.assertRaises(TypeError, get, b("foo bar"))
1403
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001404 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001405
1406 def test_set_notBefore(self):
1407 """
Alex Gaynor31287502015-09-05 16:11:27 -04001408 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1409 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1410 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001411 """
1412 self._setBoundTest("Before")
1413
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001414 def test_set_notAfter(self):
1415 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001416 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001417 GENERALIZEDTIME and sets the end of the certificate's validity period
1418 to it.
1419 """
1420 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001421
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001422 def test_get_notBefore(self):
1423 """
Alex Gaynor31287502015-09-05 16:11:27 -04001424 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1425 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001426 internally.
1427 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001428 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001429 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001430
Rick Dean38a05c82009-07-18 01:41:30 -05001431 def test_get_notAfter(self):
1432 """
Alex Gaynor31287502015-09-05 16:11:27 -04001433 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1434 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001435 internally.
1436 """
1437 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001438 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001439
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001440 def test_gmtime_adj_notBefore_wrong_args(self):
1441 """
Alex Gaynor31287502015-09-05 16:11:27 -04001442 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1443 called with the wrong number of arguments or a non-:py:obj:`int`
1444 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001445 """
1446 cert = X509()
1447 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1448 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1449 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1450
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001451 def test_gmtime_adj_notBefore(self):
1452 """
Alex Gaynor31287502015-09-05 16:11:27 -04001453 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1454 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001455 """
1456 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001457 not_before_min = (
1458 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1459 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001460 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001461 not_before = datetime.strptime(
1462 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1463 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001464 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1465 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001466
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001467 def test_gmtime_adj_notAfter_wrong_args(self):
1468 """
Alex Gaynor31287502015-09-05 16:11:27 -04001469 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1470 called with the wrong number of arguments or a non-:py:obj:`int`
1471 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001472 """
1473 cert = X509()
1474 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1475 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1476 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1477
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001478 def test_gmtime_adj_notAfter(self):
1479 """
Alex Gaynor31287502015-09-05 16:11:27 -04001480 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1481 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001482 """
1483 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001484 not_after_min = (
1485 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1486 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001487 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001488 not_after = datetime.strptime(
1489 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1490 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001491 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1492 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001493
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001494 def test_has_expired_wrong_args(self):
1495 """
Alex Gaynor31287502015-09-05 16:11:27 -04001496 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1497 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001498 """
1499 cert = X509()
1500 self.assertRaises(TypeError, cert.has_expired, None)
1501
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001502 def test_has_expired(self):
1503 """
Alex Gaynor31287502015-09-05 16:11:27 -04001504 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1505 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001506 """
1507 cert = X509()
1508 cert.gmtime_adj_notAfter(-1)
1509 self.assertTrue(cert.has_expired())
1510
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001511 def test_has_not_expired(self):
1512 """
Alex Gaynor31287502015-09-05 16:11:27 -04001513 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1514 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001515 """
1516 cert = X509()
1517 cert.gmtime_adj_notAfter(2)
1518 self.assertFalse(cert.has_expired())
1519
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001520 def test_root_has_not_expired(self):
1521 """
Alex Gaynor31287502015-09-05 16:11:27 -04001522 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1523 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001524 """
1525 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1526 self.assertFalse(cert.has_expired())
1527
Rick Dean38a05c82009-07-18 01:41:30 -05001528 def test_digest(self):
1529 """
Alex Gaynor31287502015-09-05 16:11:27 -04001530 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1531 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001532 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001533 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001534 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001535 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1536 # actually matters to the assertion (ie, another arbitrary, good
1537 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001538 # Digest verified with the command:
1539 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001540 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001541 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001542
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001543 def _extcert(self, pkey, extensions):
1544 cert = X509()
1545 cert.set_pubkey(pkey)
1546 cert.get_subject().commonName = "Unit Tests"
1547 cert.get_issuer().commonName = "Unit Tests"
1548 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1549 cert.set_notBefore(when)
1550 cert.set_notAfter(when)
1551
1552 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001553 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001554 return load_certificate(
1555 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1556
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001557 def test_extension_count(self):
1558 """
Alex Gaynor31287502015-09-05 16:11:27 -04001559 :py:obj:`X509.get_extension_count` returns the number of extensions
1560 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001561 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001562 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001563 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1564 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001565 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001566 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001567
1568 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001569 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001570 self.assertEqual(c.get_extension_count(), 0)
1571
1572 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001573 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001574 self.assertEqual(c.get_extension_count(), 1)
1575
1576 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001577 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001578 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001579
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001580 def test_get_extension(self):
1581 """
Alex Gaynor31287502015-09-05 16:11:27 -04001582 :py:obj:`X509.get_extension` takes an integer and returns an
1583 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001584 """
1585 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001586 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1587 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001588 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001589 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001590
1591 cert = self._extcert(pkey, [ca, key, subjectAltName])
1592
1593 ext = cert.get_extension(0)
1594 self.assertTrue(isinstance(ext, X509Extension))
1595 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001596 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001597
1598 ext = cert.get_extension(1)
1599 self.assertTrue(isinstance(ext, X509Extension))
1600 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001601 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001602
1603 ext = cert.get_extension(2)
1604 self.assertTrue(isinstance(ext, X509Extension))
1605 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001606 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001607
1608 self.assertRaises(IndexError, cert.get_extension, -1)
1609 self.assertRaises(IndexError, cert.get_extension, 4)
1610 self.assertRaises(TypeError, cert.get_extension, "hello")
1611
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001612 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001613 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001614 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001615 bytes and this value is reflected in the string representation of the
1616 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001617 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001618 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001619
1620 ext = cert.get_extension(3)
1621 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001622 self.assertEqual(
1623 b("DNS:altnull.python.org\x00example.com, "
1624 "email:null@python.org\x00user@example.org, "
1625 "URI:http://null.python.org\x00http://example.org, "
1626 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1627 b(str(ext)))
1628
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001629 def test_invalid_digest_algorithm(self):
1630 """
Alex Gaynor31287502015-09-05 16:11:27 -04001631 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1632 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001633 """
1634 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001635 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001636
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001637 def test_get_subject_wrong_args(self):
1638 """
Alex Gaynor31287502015-09-05 16:11:27 -04001639 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1640 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001641 """
1642 cert = X509()
1643 self.assertRaises(TypeError, cert.get_subject, None)
1644
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001645 def test_get_subject(self):
1646 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001647 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001648 """
1649 cert = load_certificate(FILETYPE_PEM, self.pemData)
1650 subj = cert.get_subject()
1651 self.assertTrue(isinstance(subj, X509Name))
1652 self.assertEquals(
1653 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001654 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1655 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001656
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001657 def test_set_subject_wrong_args(self):
1658 """
Alex Gaynor31287502015-09-05 16:11:27 -04001659 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1660 the wrong number of arguments or an argument not of type
1661 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001662 """
1663 cert = X509()
1664 self.assertRaises(TypeError, cert.set_subject)
1665 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001666 with pytest.raises(TypeError):
1667 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001668
1669 def test_set_subject(self):
1670 """
Alex Gaynor31287502015-09-05 16:11:27 -04001671 :py:obj:`X509.set_subject` changes the subject of the certificate to
1672 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001673 """
1674 cert = X509()
1675 name = cert.get_subject()
1676 name.C = 'AU'
1677 name.O = 'Unit Tests'
1678 cert.set_subject(name)
1679 self.assertEquals(
1680 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001681 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001682
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001683 def test_get_issuer_wrong_args(self):
1684 """
Alex Gaynor31287502015-09-05 16:11:27 -04001685 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1686 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001687 """
1688 cert = X509()
1689 self.assertRaises(TypeError, cert.get_issuer, None)
1690
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001691 def test_get_issuer(self):
1692 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001693 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001694 """
1695 cert = load_certificate(FILETYPE_PEM, self.pemData)
1696 subj = cert.get_issuer()
1697 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001698 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001699 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001700 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001701 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1702 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001703
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001704 def test_set_issuer_wrong_args(self):
1705 """
Alex Gaynor31287502015-09-05 16:11:27 -04001706 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1707 the wrong number of arguments or an argument not of type
1708 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001709 """
1710 cert = X509()
1711 self.assertRaises(TypeError, cert.set_issuer)
1712 self.assertRaises(TypeError, cert.set_issuer, None)
1713 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1714
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001715 def test_set_issuer(self):
1716 """
Alex Gaynor31287502015-09-05 16:11:27 -04001717 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1718 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001719 """
1720 cert = X509()
1721 name = cert.get_issuer()
1722 name.C = 'AU'
1723 name.O = 'Unit Tests'
1724 cert.set_issuer(name)
1725 self.assertEquals(
1726 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001727 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001728
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001729 def test_get_pubkey_uninitialized(self):
1730 """
Alex Gaynor31287502015-09-05 16:11:27 -04001731 When called on a certificate with no public key,
1732 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001733 """
1734 cert = X509()
1735 self.assertRaises(Error, cert.get_pubkey)
1736
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001737 def test_subject_name_hash_wrong_args(self):
1738 """
Alex Gaynor31287502015-09-05 16:11:27 -04001739 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1740 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001741 """
1742 cert = X509()
1743 self.assertRaises(TypeError, cert.subject_name_hash, None)
1744
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001745 def test_subject_name_hash(self):
1746 """
Alex Gaynor31287502015-09-05 16:11:27 -04001747 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1748 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001749 """
1750 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001751 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001752 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001753 [3350047874, # OpenSSL 0.9.8, MD5
1754 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001755 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001756
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001757 def test_get_signature_algorithm(self):
1758 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001759 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001760 the algorithm used to sign the certificate.
1761 """
1762 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001763 self.assertEqual(
1764 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001765
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001766 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001767 """
Alex Gaynor31287502015-09-05 16:11:27 -04001768 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1769 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001770 """
1771 # This certificate has been modified to indicate a bogus OID in the
1772 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001773 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001774-----BEGIN CERTIFICATE-----
1775MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1776EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1777cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1778MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1779EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1780CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1781AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1782+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1783hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1784BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1785FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1786dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1787aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1788MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1789jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1790PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1791tgI5
1792-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001793""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001794 cert = load_certificate(FILETYPE_PEM, certPEM)
1795 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001796
1797
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001798class X509StoreTests(TestCase):
1799 """
1800 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1801 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001802
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001803 def test_type(self):
1804 """
1805 :py:obj:`X509StoreType` is a type object.
1806 """
1807 self.assertIdentical(X509Store, X509StoreType)
1808 self.assertConsistentType(X509Store, 'X509Store')
1809
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001810 def test_add_cert_wrong_args(self):
1811 store = X509Store()
1812 self.assertRaises(TypeError, store.add_cert)
1813 self.assertRaises(TypeError, store.add_cert, object())
1814 self.assertRaises(TypeError, store.add_cert, X509(), object())
1815
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001816 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001817 """
1818 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1819 certificate store.
1820 """
1821 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001822 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001823 store.add_cert(cert)
1824
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001825 def test_add_cert_rejects_duplicate(self):
1826 """
Alex Gaynor31287502015-09-05 16:11:27 -04001827 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1828 an attempt is made to add the same certificate to the store more than
1829 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001830 """
1831 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1832 store = X509Store()
1833 store.add_cert(cert)
1834 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001835
1836
Rick Dean623ee362009-07-17 12:22:16 -05001837class PKCS12Tests(TestCase):
1838 """
Alex Gaynor31287502015-09-05 16:11:27 -04001839 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1840 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001841 """
1842 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1843
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001844 def test_type(self):
1845 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001846 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001847 """
1848 self.assertIdentical(PKCS12, PKCS12Type)
1849 self.assertConsistentType(PKCS12, 'PKCS12')
1850
Rick Deanf94096c2009-07-18 14:23:06 -05001851 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001852 """
Alex Gaynor31287502015-09-05 16:11:27 -04001853 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1854 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001855 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001856 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001857 self.assertEqual(None, p12.get_certificate())
1858 self.assertEqual(None, p12.get_privatekey())
1859 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001860 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001861
1862 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001863 """
Alex Gaynor31287502015-09-05 16:11:27 -04001864 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1865 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1866 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1867 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001868 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001869 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001870 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001871 self.assertRaises(TypeError, p12.set_certificate, PKey())
1872 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001873 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001874 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1875 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001876 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1877 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1878 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001879 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001880 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1881 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001882
1883 def test_key_only(self):
1884 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001885 A :py:obj:`PKCS12` with only a private key can be exported using
1886 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001887 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001888 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001889 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001890 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001891 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05001892 self.assertEqual(None, p12.get_certificate())
1893 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001894 try:
1895 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1896 except Error:
1897 # Some versions of OpenSSL will throw an exception
1898 # for this nearly useless PKCS12 we tried to generate:
1899 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1900 return
Rick Dean623ee362009-07-17 12:22:16 -05001901 p12 = load_pkcs12(dumped_p12, passwd)
1902 self.assertEqual(None, p12.get_ca_certificates())
1903 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001904
1905 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1906 # future this will be improved.
1907 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05001908
1909 def test_cert_only(self):
1910 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001911 A :py:obj:`PKCS12` with only a certificate can be exported using
1912 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001913 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001914 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001915 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001916 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001917 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05001918 self.assertEqual(cert, p12.get_certificate())
1919 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001920 try:
1921 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1922 except Error:
1923 # Some versions of OpenSSL will throw an exception
1924 # for this nearly useless PKCS12 we tried to generate:
1925 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1926 return
Rick Dean623ee362009-07-17 12:22:16 -05001927 p12 = load_pkcs12(dumped_p12, passwd)
1928 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001929
1930 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
1931 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1932
1933 # Oh ho. It puts the certificate into the ca certificates list, in
1934 # fact. Totally bogus, I would think. Nevertheless, let's exploit
1935 # that to check to see if it reconstructed the certificate we expected
1936 # it to. At some point, hopefully this will change so that
1937 # p12.get_certificate() is actually what returns the loaded
1938 # certificate.
1939 self.assertEqual(
1940 cleartextCertificatePEM,
1941 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05001942
Alex Gaynor31287502015-09-05 16:11:27 -04001943 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
1944 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05001945 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001946 Generate a PKCS12 object with components from PEM. Verify that the set
1947 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05001948 """
Rick Deanf94096c2009-07-18 14:23:06 -05001949 p12 = PKCS12()
1950 if cert_pem:
1951 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1952 self.assertEqual(ret, None)
1953 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001954 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05001955 self.assertEqual(ret, None)
1956 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04001957 ret = p12.set_ca_certificates(
1958 (load_certificate(FILETYPE_PEM, ca_pem),)
1959 )
Rick Deanf94096c2009-07-18 14:23:06 -05001960 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001961 if friendly_name:
1962 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05001963 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05001964 return p12
1965
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001966 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001967 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05001968 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001969 Use openssl program to confirm three components are recoverable from a
1970 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05001971 """
1972 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001973 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001974 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
1975 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001976 self.assertEqual(recovered_key[-len(key):], key)
1977 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001978 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001979 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
1980 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001981 self.assertEqual(recovered_cert[-len(cert):], cert)
1982 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001983 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001984 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
1985 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001986 self.assertEqual(recovered_cert[-len(ca):], ca)
1987
Stephen Holsapple38482622014-04-05 20:29:34 -07001988 def verify_pkcs12_container(self, p12):
1989 """
1990 Verify that the PKCS#12 container contains the correct client
1991 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04001992
1993 :param p12: The PKCS12 instance to verify.
1994 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07001995 """
1996 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
1997 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04001998 self.assertEqual(
1999 (client_cert_pem, client_key_pem, None),
2000 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002001
Rick Deanf94096c2009-07-18 14:23:06 -05002002 def test_load_pkcs12(self):
2003 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002004 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002005 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002006 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002007 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002008 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002009 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002010 pem,
2011 b"pkcs12",
2012 b"-export",
2013 b"-clcerts",
2014 b"-passout",
2015 b"pass:" + passwd
2016 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002017 p12 = load_pkcs12(p12_str, passphrase=passwd)
2018 self.verify_pkcs12_container(p12)
2019
Abraham Martinc5484ba2015-03-25 15:33:05 +00002020 def test_load_pkcs12_text_passphrase(self):
2021 """
2022 A PKCS12 string generated using the openssl command line can be loaded
2023 with :py:obj:`load_pkcs12` and its components extracted and examined.
2024 Using text as passphrase instead of bytes. DeprecationWarning expected.
2025 """
2026 pem = client_key_pem + client_cert_pem
2027 passwd = b"whatever"
2028 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2029 b"-passout", b"pass:" + passwd)
2030 with catch_warnings(record=True) as w:
2031 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002032 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002033
2034 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002035 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002036 WARNING_TYPE_EXPECTED
2037 ),
2038 str(w[-1].message)
2039 )
2040 self.assertIs(w[-1].category, DeprecationWarning)
2041
Abraham Martinc5484ba2015-03-25 15:33:05 +00002042 self.verify_pkcs12_container(p12)
2043
Stephen Holsapple38482622014-04-05 20:29:34 -07002044 def test_load_pkcs12_no_passphrase(self):
2045 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002046 A PKCS12 string generated using openssl command line can be loaded with
2047 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2048 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002049 """
2050 pem = client_key_pem + client_cert_pem
2051 p12_str = _runopenssl(
2052 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2053 p12 = load_pkcs12(p12_str)
2054 self.verify_pkcs12_container(p12)
2055
Stephen Holsapple38482622014-04-05 20:29:34 -07002056 def _dump_and_load(self, dump_passphrase, load_passphrase):
2057 """
2058 A helper method to dump and load a PKCS12 object.
2059 """
2060 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2061 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2062 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2063
Stephen Holsapple38482622014-04-05 20:29:34 -07002064 def test_load_pkcs12_null_passphrase_load_empty(self):
2065 """
2066 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002067 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002068 extracted and examined.
2069 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002070 self.verify_pkcs12_container(
2071 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002072
Stephen Holsapple38482622014-04-05 20:29:34 -07002073 def test_load_pkcs12_null_passphrase_load_null(self):
2074 """
2075 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002076 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002077 extracted and examined.
2078 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002079 self.verify_pkcs12_container(
2080 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002081
Stephen Holsapple38482622014-04-05 20:29:34 -07002082 def test_load_pkcs12_empty_passphrase_load_empty(self):
2083 """
2084 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002085 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002086 extracted and examined.
2087 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002088 self.verify_pkcs12_container(
2089 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002090
Stephen Holsapple38482622014-04-05 20:29:34 -07002091 def test_load_pkcs12_empty_passphrase_load_null(self):
2092 """
2093 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002094 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002095 extracted and examined.
2096 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002097 self.verify_pkcs12_container(
2098 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002099
Rick Deanee568302009-07-24 09:56:29 -05002100 def test_load_pkcs12_garbage(self):
2101 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002102 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2103 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002104 """
2105 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002106 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002107 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2108 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002109
Rick Deanf94096c2009-07-18 14:23:06 -05002110 def test_replace(self):
2111 """
Alex Gaynor31287502015-09-05 16:11:27 -04002112 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2113 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002114 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002115 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002116 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2117 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2118 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002119 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002120 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002121 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002122 self.assertEqual(1, len(p12.get_ca_certificates()))
2123 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002124 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002125 self.assertEqual(2, len(p12.get_ca_certificates()))
2126 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2127 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2128
Rick Deanf94096c2009-07-18 14:23:06 -05002129 def test_friendly_name(self):
2130 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002131 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002132 :py:obj:`PKCS12.get_friendlyname` and
2133 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2134 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002135 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002136 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002137 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002138 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002139 p12.set_friendlyname(friendly_name)
2140 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002141 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002142 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002143 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002144 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002145 # We would use the openssl program to confirm the friendly
2146 # name, but it is not possible. The pkcs12 command
2147 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002148 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002149 self.check_recovery(
2150 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2151 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002152
Rick Deanf94096c2009-07-18 14:23:06 -05002153 def test_various_empty_passphrases(self):
2154 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002155 Test that missing, None, and '' passphrases are identical for PKCS12
2156 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002157 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002158 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002159 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002160 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2161 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2162 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2163 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2164 self.check_recovery(
2165 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2166 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002167
Rick Deanf94096c2009-07-18 14:23:06 -05002168 def test_removing_ca_cert(self):
2169 """
Alex Gaynor31287502015-09-05 16:11:27 -04002170 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2171 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002172 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002173 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2174 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002175 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002176
Rick Deanf94096c2009-07-18 14:23:06 -05002177 def test_export_without_mac(self):
2178 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002179 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002180 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002181 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002182 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002183 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002184 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002185 self.check_recovery(
2186 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002187 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002188
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002189 def test_load_without_mac(self):
2190 """
2191 Loading a PKCS12 without a MAC does something other than crash.
2192 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002193 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002194 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2195 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002196 try:
2197 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2198 # The person who generated this PCKS12 should be flogged,
2199 # or better yet we should have a means to determine
2200 # whether a PCKS12 had a MAC that was verified.
2201 # Anyway, libopenssl chooses to allow it, so the
2202 # pyopenssl binding does as well.
2203 self.assertTrue(isinstance(recovered_p12, PKCS12))
2204 except Error:
2205 # Failing here with an exception is preferred as some openssl
2206 # versions do.
2207 pass
Rick Dean623ee362009-07-17 12:22:16 -05002208
Rick Dean25bcc1f2009-07-20 11:53:13 -05002209 def test_zero_len_list_for_ca(self):
2210 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002211 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002212 """
2213 passwd = 'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002214 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002215 p12.set_ca_certificates([])
2216 self.assertEqual((), p12.get_ca_certificates())
2217 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2218 self.check_recovery(
2219 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2220 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002221
Rick Deanf94096c2009-07-18 14:23:06 -05002222 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002223 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002224 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002225 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002226 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002227 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002228 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002229 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002230
Abraham Martinc5484ba2015-03-25 15:33:05 +00002231 def test_export_without_bytes(self):
2232 """
2233 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2234 """
2235 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2236
2237 with catch_warnings(record=True) as w:
2238 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002239 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002240 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002241 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002242 WARNING_TYPE_EXPECTED
2243 ),
2244 str(w[-1].message)
2245 )
2246 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002247 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002248 dumped_p12,
2249 key=server_key_pem,
2250 cert=server_cert_pem,
2251 passwd=b"randomtext"
2252 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002253
Rick Deanf94096c2009-07-18 14:23:06 -05002254 def test_key_cert_mismatch(self):
2255 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002256 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002257 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002258 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002259 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2260 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002261
2262
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002263# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002264_cmdLineQuoteRe = re.compile(br'(\\*)"')
2265_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002266
2267
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002268def cmdLineQuote(s):
2269 """
2270 Internal method for quoting a single command-line argument.
2271
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002272 See http://www.perlmonks.org/?node_id=764004
2273
Jonathan Ballet648875f2011-07-16 14:14:58 +09002274 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002275 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002276 cmd.exe-style quoting
2277
Jonathan Ballet648875f2011-07-16 14:14:58 +09002278 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002279 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002280 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002281 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2282 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002283
2284
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002285def quoteArguments(arguments):
2286 """
2287 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002288 a similar API. This allows the list passed to
2289 :py:obj:`reactor.spawnProcess` to match the child process's
2290 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002291
Jonathan Ballet648875f2011-07-16 14:14:58 +09002292 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002293 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002294
Jonathan Ballet648875f2011-07-16 14:14:58 +09002295 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002296 :return: A space-delimited string containing quoted versions of
2297 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002298 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002299 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002300
2301
Rick Dean4c9ad612009-07-17 15:05:22 -05002302def _runopenssl(pem, *args):
2303 """
2304 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002305 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002306 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002307 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002308 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002309 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2310 for arg in args
2311 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002312 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002313 command = b"openssl " + quoteArguments(args)
2314 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002315 proc.stdin.write(pem)
2316 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002317 output = proc.stdout.read()
2318 proc.stdout.close()
2319 proc.wait()
2320 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002321
2322
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002323class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002324 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002325 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002326 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002327
2328 def test_load_privatekey_invalid_format(self):
2329 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002330 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2331 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002332 """
2333 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2334
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002335 def test_load_privatekey_invalid_passphrase_type(self):
2336 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002337 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2338 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002339 """
2340 self.assertRaises(
2341 TypeError,
2342 load_privatekey,
2343 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2344
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002345 def test_load_privatekey_wrong_args(self):
2346 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002347 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2348 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002349 """
2350 self.assertRaises(TypeError, load_privatekey)
2351
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002352 def test_load_privatekey_wrongPassphrase(self):
2353 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002354 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2355 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002356 """
2357 self.assertRaises(
2358 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002359 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002360
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002361 def test_load_privatekey_passphraseWrongType(self):
2362 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002363 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2364 a passphrase with a private key encoded in a format, that doesn't
2365 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002366 """
2367 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2368 blob = dump_privatekey(FILETYPE_ASN1, key)
2369 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002370 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002371
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002372 def test_load_privatekey_passphrase(self):
2373 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002374 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2375 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002376 """
2377 key = load_privatekey(
2378 FILETYPE_PEM, encryptedPrivateKeyPEM,
2379 encryptedPrivateKeyPEMPassphrase)
2380 self.assertTrue(isinstance(key, PKeyType))
2381
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002382 def test_load_privatekey_passphrase_exception(self):
2383 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002384 If the passphrase callback raises an exception, that exception is
2385 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002386 """
2387 def cb(ignored):
2388 raise ArithmeticError
2389
Alex Gaynor791212d2015-09-05 15:46:08 -04002390 with pytest.raises(ArithmeticError):
2391 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002392
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002393 def test_load_privatekey_wrongPassphraseCallback(self):
2394 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002395 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2396 is passed an encrypted PEM and a passphrase callback which returns an
2397 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002398 """
2399 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002400
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002401 def cb(*a):
2402 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002403 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002404 self.assertRaises(
2405 Error,
2406 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2407 self.assertTrue(called)
2408
2409 def test_load_privatekey_passphraseCallback(self):
2410 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002411 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2412 encrypted PEM string if given a passphrase callback which returns the
2413 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002414 """
2415 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002416
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002417 def cb(writing):
2418 called.append(writing)
2419 return encryptedPrivateKeyPEMPassphrase
2420 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2421 self.assertTrue(isinstance(key, PKeyType))
2422 self.assertEqual(called, [False])
2423
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002424 def test_load_privatekey_passphrase_wrong_return_type(self):
2425 """
2426 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2427 callback returns something other than a byte string.
2428 """
2429 self.assertRaises(
2430 ValueError,
2431 load_privatekey,
2432 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2433
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002434 def test_dump_privatekey_wrong_args(self):
2435 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002436 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2437 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002438 """
2439 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002440 # If cipher name is given, password is required.
2441 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002442 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002443
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002444 def test_dump_privatekey_unknown_cipher(self):
2445 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002446 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2447 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002448 """
2449 key = PKey()
2450 key.generate_key(TYPE_RSA, 512)
2451 self.assertRaises(
2452 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002453 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002454
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002455 def test_dump_privatekey_invalid_passphrase_type(self):
2456 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002457 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2458 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002459 """
2460 key = PKey()
2461 key.generate_key(TYPE_RSA, 512)
2462 self.assertRaises(
2463 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002464 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002465
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002466 def test_dump_privatekey_invalid_filetype(self):
2467 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002468 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2469 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002470 """
2471 key = PKey()
2472 key.generate_key(TYPE_RSA, 512)
2473 self.assertRaises(ValueError, dump_privatekey, 100, key)
2474
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002475 def test_load_privatekey_passphraseCallbackLength(self):
2476 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002477 :py:obj:`crypto.load_privatekey` should raise an error when the
2478 passphrase provided by the callback is too long, not silently truncate
2479 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002480 """
2481 def cb(ignored):
2482 return "a" * 1025
2483
Alex Gaynor791212d2015-09-05 15:46:08 -04002484 with pytest.raises(ValueError):
2485 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002486
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002487 def test_dump_privatekey_passphrase(self):
2488 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002489 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2490 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002491 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002492 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002493 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002494 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2495 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002496 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2497 self.assertTrue(isinstance(loadedKey, PKeyType))
2498 self.assertEqual(loadedKey.type(), key.type())
2499 self.assertEqual(loadedKey.bits(), key.bits())
2500
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002501 def test_dump_privatekey_passphraseWrongType(self):
2502 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002503 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2504 a passphrase with a private key encoded in a format, that doesn't
2505 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002506 """
2507 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002508 with pytest.raises(ValueError):
2509 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002510
Rick Dean5b7b6372009-04-01 11:34:06 -05002511 def test_dump_certificate(self):
2512 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002513 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002514 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002515 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002516 cert = load_certificate(FILETYPE_PEM, pemData)
2517 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2518 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2519 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002520 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002521 self.assertEqual(dumped_der, good_der)
2522 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2523 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2524 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2525 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002526 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002527 self.assertEqual(dumped_text, good_text)
2528
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002529 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002530 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002531 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002532 """
2533 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002534 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002535 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2536 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002537
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002538 def test_dump_privatekey_asn1(self):
2539 """
2540 :py:obj:`dump_privatekey` writes a DER
2541 """
2542 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2543 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2544
Rick Dean5b7b6372009-04-01 11:34:06 -05002545 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002546 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002547 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002548 self.assertEqual(dumped_der, good_der)
2549 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2550 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2551 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002552
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002553 def test_dump_privatekey_text(self):
2554 """
2555 :py:obj:`dump_privatekey` writes a text
2556 """
2557 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2558 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2559
Rick Dean5b7b6372009-04-01 11:34:06 -05002560 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002561 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002562 self.assertEqual(dumped_text, good_text)
2563
2564 def test_dump_certificate_request(self):
2565 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002566 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002567 """
Alex Gaynor31287502015-09-05 16:11:27 -04002568 req = load_certificate_request(
2569 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002570 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2571 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2572 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002573 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002574 self.assertEqual(dumped_der, good_der)
2575 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2576 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2577 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2578 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002579 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002580 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002581 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002582
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002583 def test_dump_privatekey_passphraseCallback(self):
2584 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002585 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2586 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002587 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002588 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002589 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002590
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002591 def cb(writing):
2592 called.append(writing)
2593 return passphrase
2594 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002595 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2596 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002597 self.assertEqual(called, [True])
2598 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2599 self.assertTrue(isinstance(loadedKey, PKeyType))
2600 self.assertEqual(loadedKey.type(), key.type())
2601 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002602
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002603 def test_dump_privatekey_passphrase_exception(self):
2604 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002605 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002606 by the passphrase callback.
2607 """
2608 def cb(ignored):
2609 raise ArithmeticError
2610
2611 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002612 with pytest.raises(ArithmeticError):
2613 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002614
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002615 def test_dump_privatekey_passphraseCallbackLength(self):
2616 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002617 :py:obj:`crypto.dump_privatekey` should raise an error when the
2618 passphrase provided by the callback is too long, not silently truncate
2619 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002620 """
2621 def cb(ignored):
2622 return "a" * 1025
2623
2624 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002625 with pytest.raises(ValueError):
2626 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002627
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002628 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002629 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002630 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2631 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002632 """
2633 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2634 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2635
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002636 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002637 """
2638 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2639 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2640 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002641 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2642 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2643
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002644 def test_load_pkcs7_data_invalid(self):
2645 """
2646 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2647 :py:obj:`Error` is raised.
2648 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002649 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002650
2651
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002652class LoadCertificateTests(TestCase):
2653 """
2654 Tests for :py:obj:`load_certificate_request`.
2655 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002656
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002657 def test_badFileType(self):
2658 """
2659 If the file type passed to :py:obj:`load_certificate_request` is
2660 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2661 :py:class:`ValueError` is raised.
2662 """
2663 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2664
2665
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002666class PKCS7Tests(TestCase):
2667 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002668 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002669 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002670
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002671 def test_type(self):
2672 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002673 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002674 """
2675 self.assertTrue(isinstance(PKCS7Type, type))
2676 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2677
2678 # XXX This doesn't currently work.
2679 # self.assertIdentical(PKCS7, PKCS7Type)
2680
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002681 # XXX Opposite results for all these following methods
2682
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002683 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002684 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002685 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2686 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002687 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002688 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2689 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2690
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002691 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002692 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002693 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2694 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002695 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002696 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2697 self.assertTrue(pkcs7.type_is_signed())
2698
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002699 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002700 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002701 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2702 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002703 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002704 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2705 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2706
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002707 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002708 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002709 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2710 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002711 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002712 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2713 self.assertFalse(pkcs7.type_is_enveloped())
2714
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002715 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002716 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002717 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2718 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002719 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002720 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2721 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2722
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002723 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002724 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002725 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2726 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002727 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002728 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2729 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2730
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002731 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002732 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002733 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2734 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002735 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002736 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2737 self.assertFalse(pkcs7.type_is_data())
2738
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002739 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002740 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002741 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2742 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002743 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002744 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2745 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2746
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002747 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002748 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002749 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2750 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002751 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002752 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2753 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2754
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002755 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002756 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002757 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2758 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002759 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002760 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002761 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002762
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002763 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002764 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002765 If an attribute other than one of the methods tested here is accessed
2766 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2767 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002768 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002769 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2770 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2771
2772
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002773class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002774 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002775 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002776 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002777
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002778 def signable(self):
2779 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002780 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002781 """
2782 return NetscapeSPKI()
2783
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002784 def test_type(self):
2785 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002786 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2787 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002788 """
2789 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2790 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2791
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002792 def test_construction(self):
2793 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002794 :py:obj:`NetscapeSPKI` returns an instance of
2795 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002796 """
2797 nspki = NetscapeSPKI()
2798 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2799
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002800 def test_invalid_attribute(self):
2801 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002802 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2803 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002804 """
2805 nspki = NetscapeSPKI()
2806 self.assertRaises(AttributeError, lambda: nspki.foo)
2807
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002808 def test_b64_encode(self):
2809 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002810 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2811 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002812 """
2813 nspki = NetscapeSPKI()
2814 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002815 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002816
2817
Rick Dean536ba022009-07-24 23:57:27 -05002818class RevokedTests(TestCase):
2819 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002820 Tests for :py:obj:`OpenSSL.crypto.Revoked`
Rick Dean536ba022009-07-24 23:57:27 -05002821 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002822
Rick Dean536ba022009-07-24 23:57:27 -05002823 def test_construction(self):
2824 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002825 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002826 that it is empty.
2827 """
2828 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002829 self.assertTrue(isinstance(revoked, Revoked))
2830 self.assertEquals(type(revoked), Revoked)
2831 self.assertEquals(revoked.get_serial(), b('00'))
2832 self.assertEquals(revoked.get_rev_date(), None)
2833 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05002834
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002835 def test_construction_wrong_args(self):
2836 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002837 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
2838 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002839 """
2840 self.assertRaises(TypeError, Revoked, None)
2841 self.assertRaises(TypeError, Revoked, 1)
2842 self.assertRaises(TypeError, Revoked, "foo")
2843
Rick Dean536ba022009-07-24 23:57:27 -05002844 def test_serial(self):
2845 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002846 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002847 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002848 with grace.
2849 """
2850 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002851 ret = revoked.set_serial(b('10b'))
2852 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002853 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002854 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05002855
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002856 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05002857 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002858 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05002859
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002860 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05002861 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002862 self.assertRaises(TypeError, revoked.get_serial, 1)
2863 self.assertRaises(TypeError, revoked.get_serial, None)
2864 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05002865
Rick Dean536ba022009-07-24 23:57:27 -05002866 def test_date(self):
2867 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002868 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002869 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002870 with grace.
2871 """
2872 revoked = Revoked()
2873 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002874 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05002875
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002876 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002877 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002878 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002879 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002880 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05002881
Rick Dean6385faf2009-07-26 00:07:47 -05002882 def test_reason(self):
2883 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002884 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002885 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05002886 as "set". Likewise, each reason of all_reasons() must work.
2887 """
2888 revoked = Revoked()
2889 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002890 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05002891 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002892 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05002893 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002894 self.assertEquals(
2895 reason.lower().replace(b(' '), b('')),
2896 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002897 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05002898
2899 revoked.set_reason(None)
2900 self.assertEqual(revoked.get_reason(), None)
2901
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002902 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05002903 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002904 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002905 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002906 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05002907 """
2908 revoked = Revoked()
2909 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04002910 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05002911
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002912 def test_get_reason_wrong_arguments(self):
2913 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002914 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
2915 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002916 """
2917 revoked = Revoked()
2918 self.assertRaises(TypeError, revoked.get_reason, None)
2919 self.assertRaises(TypeError, revoked.get_reason, 1)
2920 self.assertRaises(TypeError, revoked.get_reason, "foo")
2921
2922
Rick Dean536ba022009-07-24 23:57:27 -05002923class CRLTests(TestCase):
2924 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002925 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05002926 """
2927 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2928 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2929
2930 def test_construction(self):
2931 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002932 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002933 that it is empty
2934 """
2935 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04002936 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05002937 self.assertEqual(crl.get_revoked(), None)
2938
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05002939 def test_construction_wrong_args(self):
2940 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002941 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
2942 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05002943 """
2944 self.assertRaises(TypeError, CRL, 1)
2945 self.assertRaises(TypeError, CRL, "")
2946 self.assertRaises(TypeError, CRL, None)
2947
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002948 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05002949 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002950 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05002951 """
2952 crl = CRL()
2953 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002954 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002955 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002956 revoked.set_serial(b('3ab'))
2957 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05002958 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002959 return crl
Rick Dean536ba022009-07-24 23:57:27 -05002960
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002961 def test_export_pem(self):
2962 """
2963 If not passed a format, ``CRL.export`` returns a "PEM" format string
2964 representing a serial number, a revoked reason, and certificate issuer
2965 information.
2966 """
2967 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05002968 # PEM format
2969 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002970 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002971
2972 # These magic values are based on the way the CRL above was constructed
2973 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002974 text.index(b('Serial Number: 03AB'))
2975 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002976 text.index(
2977 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
2978 )
2979
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002980 def test_export_der(self):
2981 """
2982 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
2983 "DER" format string representing a serial number, a revoked reason, and
2984 certificate issuer information.
2985 """
2986 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05002987
2988 # DER format
2989 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002990 text = _runopenssl(
2991 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
2992 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002993 text.index(b('Serial Number: 03AB'))
2994 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002995 text.index(
2996 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
2997 )
2998
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002999 def test_export_text(self):
3000 """
3001 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3002 text format string like the one produced by the openssl command line
3003 tool.
3004 """
3005 crl = self._get_crl()
3006
3007 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3008 text = _runopenssl(
3009 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3010 )
Rick Dean536ba022009-07-24 23:57:27 -05003011
3012 # text format
3013 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3014 self.assertEqual(text, dumped_text)
3015
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003016 def test_export_custom_digest(self):
3017 """
3018 If passed the name of a digest function, ``CRL.export`` uses a
3019 signature algorithm based on that digest function.
3020 """
3021 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003022 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003023 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3024 text.index(b('Signature Algorithm: sha1'))
3025
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003026 def test_export_md5_digest(self):
3027 """
3028 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3029 not emit a deprecation warning.
3030 """
3031 crl = self._get_crl()
3032 with catch_warnings(record=True) as catcher:
3033 simplefilter("always")
3034 self.assertEqual(0, len(catcher))
3035 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3036 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3037 text.index(b('Signature Algorithm: md5'))
3038
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003039 def test_export_default_digest(self):
3040 """
3041 If not passed the name of a digest function, ``CRL.export`` uses a
3042 signature algorithm based on MD5 and emits a deprecation warning.
3043 """
3044 crl = self._get_crl()
3045 with catch_warnings(record=True) as catcher:
3046 simplefilter("always")
3047 dumped_crl = crl.export(self.cert, self.pkey)
3048 self.assertEqual(
3049 "The default message digest (md5) is deprecated. "
3050 "Pass the name of a message digest explicitly.",
3051 str(catcher[0].message),
3052 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003053 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3054 text.index(b('Signature Algorithm: md5'))
3055
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003056 def test_export_invalid(self):
3057 """
3058 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003059 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003060 """
3061 crl = CRL()
3062 self.assertRaises(Error, crl.export, X509(), PKey())
3063
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003064 def test_add_revoked_keyword(self):
3065 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003066 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003067 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003068 """
3069 crl = CRL()
3070 revoked = Revoked()
3071 crl.add_revoked(revoked=revoked)
3072 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3073
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003074 def test_export_wrong_args(self):
3075 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003076 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003077 four arguments, or with arguments other than the certificate,
3078 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003079 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003080 """
3081 crl = CRL()
3082 self.assertRaises(TypeError, crl.export)
3083 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003084 with pytest.raises(TypeError):
3085 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3086 with pytest.raises(TypeError):
3087 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3088 with pytest.raises(TypeError):
3089 crl.export(self.cert, None, FILETYPE_PEM, 10)
3090 with pytest.raises(TypeError):
3091 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003092 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3093
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003094 def test_export_unknown_filetype(self):
3095 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003096 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003097 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3098 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003099 """
3100 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003101 with pytest.raises(ValueError):
3102 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003103
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003104 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003105 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003106 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003107 in a :py:obj:`ValueError` being raised.
3108 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003109 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003110 self.assertRaises(
3111 ValueError,
3112 crl.export,
3113 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3114 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003115
Rick Dean536ba022009-07-24 23:57:27 -05003116 def test_get_revoked(self):
3117 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003118 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003119 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3120 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003121 """
3122 crl = CRL()
3123
3124 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003125 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003126 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003127 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003128 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003129 revoked.set_serial(b('100'))
3130 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003131 crl.add_revoked(revoked)
3132
3133 revs = crl.get_revoked()
3134 self.assertEqual(len(revs), 2)
3135 self.assertEqual(type(revs[0]), Revoked)
3136 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003137 self.assertEqual(revs[0].get_serial(), b('03AB'))
3138 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003139 self.assertEqual(revs[0].get_rev_date(), now)
3140 self.assertEqual(revs[1].get_rev_date(), now)
3141
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003142 def test_get_revoked_wrong_args(self):
3143 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003144 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3145 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003146 """
3147 crl = CRL()
3148 self.assertRaises(TypeError, crl.get_revoked, None)
3149 self.assertRaises(TypeError, crl.get_revoked, 1)
3150 self.assertRaises(TypeError, crl.get_revoked, "")
3151 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3152
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003153 def test_add_revoked_wrong_args(self):
3154 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003155 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3156 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003157 """
3158 crl = CRL()
3159 self.assertRaises(TypeError, crl.add_revoked)
3160 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3161 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3162
Rick Dean536ba022009-07-24 23:57:27 -05003163 def test_load_crl(self):
3164 """
3165 Load a known CRL and inspect its revocations. Both
3166 PEM and DER formats are loaded.
3167 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003168 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003169 revs = crl.get_revoked()
3170 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003171 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003172 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003173 self.assertEqual(revs[1].get_serial(), b('0100'))
3174 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003175
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003176 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003177 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003178 revs = crl.get_revoked()
3179 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003180 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003181 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003182 self.assertEqual(revs[1].get_serial(), b('0100'))
3183 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003184
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003185 def test_load_crl_wrong_args(self):
3186 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003187 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3188 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003189 """
3190 self.assertRaises(TypeError, load_crl)
3191 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3192 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3193
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003194 def test_load_crl_bad_filetype(self):
3195 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003196 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3197 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003198 """
3199 self.assertRaises(ValueError, load_crl, 100, crlData)
3200
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003201 def test_load_crl_bad_data(self):
3202 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003203 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3204 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003205 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003206 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003207
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003208
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003209class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003210 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003211 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003212 """
3213 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3214 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003215 intermediate_server_cert = load_certificate(
3216 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003217
3218 def test_valid(self):
3219 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003220 :py:obj:`verify_certificate` returns ``None`` when called with a
3221 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003222 """
3223 store = X509Store()
3224 store.add_cert(self.root_cert)
3225 store.add_cert(self.intermediate_cert)
3226 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003227 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003228
3229 def test_reuse(self):
3230 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003231 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003232 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003233 """
3234 store = X509Store()
3235 store.add_cert(self.root_cert)
3236 store.add_cert(self.intermediate_cert)
3237 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003238 self.assertEqual(store_ctx.verify_certificate(), None)
3239 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003240
3241 def test_trusted_self_signed(self):
3242 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003243 :py:obj:`verify_certificate` returns ``None`` when called with a
3244 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003245 """
3246 store = X509Store()
3247 store.add_cert(self.root_cert)
3248 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003249 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003250
3251 def test_untrusted_self_signed(self):
3252 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003253 :py:obj:`verify_certificate` raises error when a self-signed
3254 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003255 """
3256 store = X509Store()
3257 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003258 with pytest.raises(X509StoreContextError) as exc:
3259 store_ctx.verify_certificate()
3260
3261 assert exc.value.args[0][2] == 'self signed certificate'
3262 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003263
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003264 def test_invalid_chain_no_root(self):
3265 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003266 :py:obj:`verify_certificate` raises error when a root certificate is
3267 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003268 """
3269 store = X509Store()
3270 store.add_cert(self.intermediate_cert)
3271 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003272
3273 with pytest.raises(X509StoreContextError) as exc:
3274 store_ctx.verify_certificate()
3275
3276 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3277 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003278
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003279 def test_invalid_chain_no_intermediate(self):
3280 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003281 :py:obj:`verify_certificate` raises error when an intermediate
3282 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003283 """
3284 store = X509Store()
3285 store.add_cert(self.root_cert)
3286 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003287
Alex Gaynor85b49702015-09-05 16:30:59 -04003288 with pytest.raises(X509StoreContextError) as exc:
3289 store_ctx.verify_certificate()
3290
3291 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3292 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003293
Stephen Holsapple46a09252015-02-12 14:45:43 -08003294 def test_modification_pre_verify(self):
3295 """
3296 :py:obj:`verify_certificate` can use a store context modified after
3297 instantiation.
3298 """
3299 store_bad = X509Store()
3300 store_bad.add_cert(self.intermediate_cert)
3301 store_good = X509Store()
3302 store_good.add_cert(self.root_cert)
3303 store_good.add_cert(self.intermediate_cert)
3304 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003305
3306 with pytest.raises(X509StoreContextError) as exc:
3307 store_ctx.verify_certificate()
3308
3309 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3310 assert exc.value.certificate.get_subject().CN == 'intermediate'
3311
Stephen Holsapple46a09252015-02-12 14:45:43 -08003312 store_ctx.set_store(store_good)
3313 self.assertEqual(store_ctx.verify_certificate(), None)
3314
3315
James Yonan7c2e5d32010-02-27 05:45:50 -07003316class SignVerifyTests(TestCase):
3317 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003318 Tests for :py:obj:`OpenSSL.crypto.sign` and
3319 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003320 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003321
James Yonan7c2e5d32010-02-27 05:45:50 -07003322 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003323 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003324 :py:obj:`sign` generates a cryptographic signature which
3325 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003326 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003327 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003328 "It was a bright cold day in April, and the clocks were striking "
3329 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3330 "effort to escape the vile wind, slipped quickly through the "
3331 "glass doors of Victory Mansions, though not quickly enough to "
3332 "prevent a swirl of gritty dust from entering along with him.")
3333
3334 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003335 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003336 # verify the content with this cert
3337 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3338 # certificate unrelated to priv_key, used to trigger an error
3339 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003340
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003341 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003342 sig = sign(priv_key, content, digest)
3343
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003344 # Verify the signature of content, will throw an exception if
3345 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003346 verify(good_cert, sig, content, digest)
3347
3348 # This should fail because the certificate doesn't match the
3349 # private key that was used to sign the content.
3350 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3351
3352 # This should fail because we've "tainted" the content after
3353 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003354 self.assertRaises(
3355 Error, verify,
3356 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003357
3358 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003359 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003360 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003361 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003362 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003363
Abraham Martinc5484ba2015-03-25 15:33:05 +00003364 def test_sign_verify_with_text(self):
3365 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003366 :py:obj:`sign` generates a cryptographic signature which
3367 :py:obj:`verify` can check. Deprecation warnings raised because using
3368 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003369 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003370 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003371 b"It was a bright cold day in April, and the clocks were striking "
3372 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3373 b"effort to escape the vile wind, slipped quickly through the "
3374 b"glass doors of Victory Mansions, though not quickly enough to "
3375 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003376 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003377
3378 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3379 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3380 for digest in ['md5', 'sha1']:
3381 with catch_warnings(record=True) as w:
3382 simplefilter("always")
3383 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003384
3385 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003386 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003387 WARNING_TYPE_EXPECTED
3388 ),
3389 str(w[-1].message)
3390 )
3391 self.assertIs(w[-1].category, DeprecationWarning)
3392
Abraham Martinc5484ba2015-03-25 15:33:05 +00003393 with catch_warnings(record=True) as w:
3394 simplefilter("always")
3395 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003396
3397 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003398 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003399 WARNING_TYPE_EXPECTED
3400 ),
3401 str(w[-1].message)
3402 )
3403 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003404
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003405 def test_sign_nulls(self):
3406 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003407 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003408 """
3409 content = b("Watch out! \0 Did you see it?")
3410 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3411 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3412 sig = sign(priv_key, content, "sha1")
3413 verify(good_cert, sig, content, "sha1")
3414
3415
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003416class EllipticCurveTests(TestCase):
3417 """
3418 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3419 :py:obj:`get_elliptic_curves`.
3420 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003421
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003422 def test_set(self):
3423 """
3424 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3425 """
3426 self.assertIsInstance(get_elliptic_curves(), set)
3427
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003428 def test_some_curves(self):
3429 """
3430 If :py:mod:`cryptography` has elliptic curve support then the set
3431 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3432 it.
3433
3434 There could be an OpenSSL that violates this assumption. If so, this
3435 test will fail and we'll find out.
3436 """
3437 curves = get_elliptic_curves()
3438 if lib.Cryptography_HAS_EC:
3439 self.assertTrue(curves)
3440 else:
3441 self.assertFalse(curves)
3442
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003443 def test_a_curve(self):
3444 """
3445 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3446 supported curve.
3447 """
3448 curves = get_elliptic_curves()
3449 if curves:
3450 curve = next(iter(curves))
3451 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3452 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003453 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003454
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003455 def test_not_a_curve(self):
3456 """
3457 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3458 with a name which does not identify a supported curve.
3459 """
3460 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003461 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003462
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003463 def test_repr(self):
3464 """
3465 The string representation of a curve object includes simply states the
3466 object is a curve and what its name is.
3467 """
3468 curves = get_elliptic_curves()
3469 if curves:
3470 curve = next(iter(curves))
3471 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3472
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003473 def test_to_EC_KEY(self):
3474 """
3475 The curve object can export a version of itself as an EC_KEY* via the
3476 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3477 """
3478 curves = get_elliptic_curves()
3479 if curves:
3480 curve = next(iter(curves))
3481 # It's not easy to assert anything about this object. However, see
3482 # leakcheck/crypto.py for a test that demonstrates it at least does
3483 # not leak memory.
3484 curve._to_EC_KEY()
3485
3486
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003487class EllipticCurveFactory(object):
3488 """
3489 A helper to get the names of two curves.
3490 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003491
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003492 def __init__(self):
3493 curves = iter(get_elliptic_curves())
3494 try:
3495 self.curve_name = next(curves).name
3496 self.another_curve_name = next(curves).name
3497 except StopIteration:
3498 self.curve_name = self.another_curve_name = None
3499
3500
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003501class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3502 """
3503 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3504 """
3505 curve_factory = EllipticCurveFactory()
3506
3507 if curve_factory.curve_name is None:
3508 skip = "There are no curves available there can be no curve objects."
3509
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003510 def anInstance(self):
3511 """
3512 Get the curve object for an arbitrary curve supported by the system.
3513 """
3514 return get_elliptic_curve(self.curve_factory.curve_name)
3515
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003516 def anotherInstance(self):
3517 """
3518 Get the curve object for an arbitrary curve supported by the system -
3519 but not the one returned by C{anInstance}.
3520 """
3521 return get_elliptic_curve(self.curve_factory.another_curve_name)
3522
3523
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003524class EllipticCurveHashTests(TestCase):
3525 """
3526 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3527 as an item in a :py:type:`dict` or :py:type:`set`).
3528 """
3529 curve_factory = EllipticCurveFactory()
3530
3531 if curve_factory.curve_name is None:
3532 skip = "There are no curves available there can be no curve objects."
3533
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003534 def test_contains(self):
3535 """
3536 The ``in`` operator reports that a :py:type:`set` containing a curve
3537 does contain that curve.
3538 """
3539 curve = get_elliptic_curve(self.curve_factory.curve_name)
3540 curves = set([curve])
3541 self.assertIn(curve, curves)
3542
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003543 def test_does_not_contain(self):
3544 """
3545 The ``in`` operator reports that a :py:type:`set` not containing a
3546 curve does not contain that curve.
3547 """
3548 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003549 curves = set([
3550 get_elliptic_curve(self.curve_factory.another_curve_name)
3551 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003552 self.assertNotIn(curve, curves)
3553
3554
Rick Dean5b7b6372009-04-01 11:34:06 -05003555if __name__ == '__main__':
3556 main()