blob: c0073f36aa7b9252daeee57da2227e1f7d864e58 [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)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400433 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Alex Gaynor7f636492015-09-04 13:26:52 -0400434 expire = b((datetime.now() + timedelta(days=100)).strftime("%Y%m%d%H%M%SZ"))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400435 self.x509.set_notBefore(now)
436 self.x509.set_notAfter(expire)
437
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())
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500789 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400790 def key(attr):
791 return attr[1]
792 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500793 for k, v in attrs:
794 setattr(name, k, v)
795 return name
796
Rick Deane15b1472009-07-09 15:53:42 -0500797 def test_type(self):
798 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900799 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500800 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400801 self.assertIdentical(X509Name, X509NameType)
802 self.assertEqual(X509NameType.__name__, 'X509Name')
803 self.assertTrue(isinstance(X509NameType, type))
804
Rick Deane15b1472009-07-09 15:53:42 -0500805 name = self._x509name()
806 self.assertTrue(
807 isinstance(name, X509NameType),
808 "%r is of type %r, should be %r" % (
809 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500810
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400811 def test_onlyStringAttributes(self):
812 """
Alex Gaynor31287502015-09-05 16:11:27 -0400813 Attempting to set a non-:py:data:`str` attribute name on an
814 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
815 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400816 """
817 name = self._x509name()
818 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400819 # rejected. Sorry, you're wrong. unicode is automatically converted
820 # to str outside of the control of X509Name, so there's no way to
821 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800822
Alex Gaynor31287502015-09-05 16:11:27 -0400823 # Also, this used to test str subclasses, but that test is less
824 # relevant now that the implementation is in Python instead of C. Also
825 # PyPy automatically converts str subclasses to str when they are
826 # passed to setattr, so we can't test it on PyPy. Apparently CPython
827 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400828 self.assertRaises(TypeError, setattr, name, None, "hello")
829 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400830
831 def test_setInvalidAttribute(self):
832 """
Alex Gaynor31287502015-09-05 16:11:27 -0400833 Attempting to set any attribute name on an :py:class:`X509NameType`
834 instance for which no corresponding NID is defined causes
835 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400836 """
837 name = self._x509name()
838 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
839
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500840 def test_attributes(self):
841 """
Alex Gaynor31287502015-09-05 16:11:27 -0400842 :py:class:`X509NameType` instances have attributes for each standard
843 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500844 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500845 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500846 name.commonName = "foo"
847 self.assertEqual(name.commonName, "foo")
848 self.assertEqual(name.CN, "foo")
849 name.CN = "baz"
850 self.assertEqual(name.commonName, "baz")
851 self.assertEqual(name.CN, "baz")
852 name.commonName = "bar"
853 self.assertEqual(name.commonName, "bar")
854 self.assertEqual(name.CN, "bar")
855 name.CN = "quux"
856 self.assertEqual(name.commonName, "quux")
857 self.assertEqual(name.CN, "quux")
858
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500859 def test_copy(self):
860 """
Alex Gaynor31287502015-09-05 16:11:27 -0400861 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
862 with all the same attributes as an existing :py:class:`X509NameType`
863 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500864 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500865 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500866
867 copy = X509Name(name)
868 self.assertEqual(copy.commonName, "foo")
869 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500870
871 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500872 copy.commonName = "baz"
873 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500874
875 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500876 name.emailAddress = "quux@example.com"
877 self.assertEqual(copy.emailAddress, "bar@example.com")
878
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500879 def test_repr(self):
880 """
Alex Gaynor31287502015-09-05 16:11:27 -0400881 :py:func:`repr` passed an :py:class:`X509NameType` instance should
882 return a string containing a description of the type and the NIDs which
883 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500884 """
885 name = self._x509name(commonName="foo", emailAddress="bar")
886 self.assertEqual(
887 repr(name),
888 "<X509Name object '/emailAddress=bar/CN=foo'>")
889
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500890 def test_comparison(self):
891 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900892 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500893 """
894 def _equality(a, b, assertTrue, assertFalse):
895 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
896 assertFalse(a != b)
897 assertTrue(b == a)
898 assertFalse(b != a)
899
900 def assertEqual(a, b):
901 _equality(a, b, self.assertTrue, self.assertFalse)
902
903 # Instances compare equal to themselves.
904 name = self._x509name()
905 assertEqual(name, name)
906
907 # Empty instances should compare equal to each other.
908 assertEqual(self._x509name(), self._x509name())
909
910 # Instances with equal NIDs should compare equal to each other.
911 assertEqual(self._x509name(commonName="foo"),
912 self._x509name(commonName="foo"))
913
914 # Instance with equal NIDs set using different aliases should compare
915 # equal to each other.
916 assertEqual(self._x509name(commonName="foo"),
917 self._x509name(CN="foo"))
918
919 # Instances with more than one NID with the same values should compare
920 # equal to each other.
921 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
922 self._x509name(commonName="foo", OU="bar"))
923
924 def assertNotEqual(a, b):
925 _equality(a, b, self.assertFalse, self.assertTrue)
926
927 # Instances with different values for the same NID should not compare
928 # equal to each other.
929 assertNotEqual(self._x509name(CN="foo"),
930 self._x509name(CN="bar"))
931
932 # Instances with different NIDs should not compare equal to each other.
933 assertNotEqual(self._x509name(CN="foo"),
934 self._x509name(OU="foo"))
935
936 def _inequality(a, b, assertTrue, assertFalse):
937 assertTrue(a < b)
938 assertTrue(a <= b)
939 assertTrue(b > a)
940 assertTrue(b >= a)
941 assertFalse(a > b)
942 assertFalse(a >= b)
943 assertFalse(b < a)
944 assertFalse(b <= a)
945
946 def assertLessThan(a, b):
947 _inequality(a, b, self.assertTrue, self.assertFalse)
948
949 # An X509Name with a NID with a value which sorts less than the value
950 # of the same NID on another X509Name compares less than the other
951 # X509Name.
952 assertLessThan(self._x509name(CN="abc"),
953 self._x509name(CN="def"))
954
955 def assertGreaterThan(a, b):
956 _inequality(a, b, self.assertFalse, self.assertTrue)
957
958 # An X509Name with a NID with a value which sorts greater than the
959 # value of the same NID on another X509Name compares greater than the
960 # other X509Name.
961 assertGreaterThan(self._x509name(CN="def"),
962 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500963
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400964 def test_hash(self):
965 """
Alex Gaynor31287502015-09-05 16:11:27 -0400966 :py:meth:`X509Name.hash` returns an integer hash based on the value of
967 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400968 """
969 a = self._x509name(CN="foo")
970 b = self._x509name(CN="foo")
971 self.assertEqual(a.hash(), b.hash())
972 a.CN = "bar"
973 self.assertNotEqual(a.hash(), b.hash())
974
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400975 def test_der(self):
976 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900977 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400978 """
979 a = self._x509name(CN="foo", C="US")
980 self.assertEqual(
981 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400982 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +0200983 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400984
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400985 def test_get_components(self):
986 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900987 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
988 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400989 giving the NIDs and associated values which make up the name.
990 """
991 a = self._x509name()
992 self.assertEqual(a.get_components(), [])
993 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400994 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400995 a.organizationalUnitName = "bar"
996 self.assertEqual(
997 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400998 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400999
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001000 def test_load_nul_byte_attribute(self):
1001 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001002 An :py:class:`OpenSSL.crypto.X509Name` from an
1003 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001004 NUL byte in the value of one of its attributes.
1005 """
1006 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1007 subject = cert.get_subject()
1008 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001009 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001010
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001011 def test_setAttributeFailure(self):
1012 """
1013 If the value of an attribute cannot be set for some reason then
1014 :py:class:`OpenSSL.crypto.Error` is raised.
1015 """
1016 name = self._x509name()
1017 # This value is too long
1018 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1019
1020
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001021class _PKeyInteractionTestsMixin:
1022 """
1023 Tests which involve another thing and a PKey.
1024 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001025
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001026 def signable(self):
1027 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001028 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1029 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001030 """
1031 raise NotImplementedError()
1032
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001033 def test_signWithUngenerated(self):
1034 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001035 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1036 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001037 """
1038 request = self.signable()
1039 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001040 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001041
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001042 def test_signWithPublicKey(self):
1043 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001044 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1045 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001046 """
1047 request = self.signable()
1048 key = PKey()
1049 key.generate_key(TYPE_RSA, 512)
1050 request.set_pubkey(key)
1051 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001052 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001053
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001054 def test_signWithUnknownDigest(self):
1055 """
Alex Gaynor31287502015-09-05 16:11:27 -04001056 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1057 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001058 """
1059 request = self.signable()
1060 key = PKey()
1061 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001062 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001063
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001064 def test_sign(self):
1065 """
Alex Gaynor31287502015-09-05 16:11:27 -04001066 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1067 valid digest function. :py:meth:`X509Req.verify` can be used to check
1068 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001069 """
1070 request = self.signable()
1071 key = PKey()
1072 key.generate_key(TYPE_RSA, 512)
1073 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001074 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001075 # If the type has a verify method, cover that too.
1076 if getattr(request, 'verify', None) is not None:
1077 pub = request.get_pubkey()
1078 self.assertTrue(request.verify(pub))
1079 # Make another key that won't verify.
1080 key = PKey()
1081 key.generate_key(TYPE_RSA, 512)
1082 self.assertRaises(Error, request.verify, key)
1083
1084
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001085class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001086 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001087 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001088 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001089
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001090 def signable(self):
1091 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001092 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001093 """
1094 return X509Req()
1095
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001096 def test_type(self):
1097 """
Alex Gaynor31287502015-09-05 16:11:27 -04001098 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1099 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001100 """
1101 self.assertIdentical(X509Req, X509ReqType)
1102 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001103
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001104 def test_construction(self):
1105 """
Alex Gaynor31287502015-09-05 16:11:27 -04001106 :py:obj:`X509Req` takes no arguments and returns an
1107 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001108 """
1109 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001110 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001111
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001112 def test_version(self):
1113 """
Alex Gaynor31287502015-09-05 16:11:27 -04001114 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1115 certificate request. :py:obj:`X509ReqType.get_version` returns the
1116 X.509 version of the certificate request. The initial value of the
1117 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001118 """
1119 request = X509Req()
1120 self.assertEqual(request.get_version(), 0)
1121 request.set_version(1)
1122 self.assertEqual(request.get_version(), 1)
1123 request.set_version(3)
1124 self.assertEqual(request.get_version(), 3)
1125
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001126 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001127 """
Alex Gaynor31287502015-09-05 16:11:27 -04001128 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1129 with the wrong number of arguments or with a non-:py:obj:`int`
1130 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1131 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001132 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001133 request = X509Req()
1134 self.assertRaises(TypeError, request.set_version)
1135 self.assertRaises(TypeError, request.set_version, "foo")
1136 self.assertRaises(TypeError, request.set_version, 1, 2)
1137 self.assertRaises(TypeError, request.get_version, None)
1138
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001139 def test_get_subject(self):
1140 """
Alex Gaynor31287502015-09-05 16:11:27 -04001141 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1142 subject of the request and which is valid even after the request object
1143 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001144 """
1145 request = X509Req()
1146 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001147 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001148 subject.commonName = "foo"
1149 self.assertEqual(request.get_subject().commonName, "foo")
1150 del request
1151 subject.commonName = "bar"
1152 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001153
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001154 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001155 """
Alex Gaynor31287502015-09-05 16:11:27 -04001156 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1157 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001158 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001159 request = X509Req()
1160 self.assertRaises(TypeError, request.get_subject, None)
1161
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001162 def test_add_extensions(self):
1163 """
Alex Gaynor31287502015-09-05 16:11:27 -04001164 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1165 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001166 """
1167 request = X509Req()
1168 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001169 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001170 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001171 self.assertEqual(len(exts), 1)
1172 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1173 self.assertEqual(exts[0].get_critical(), 1)
1174 self.assertEqual(exts[0].get_data(), b('0\x00'))
1175
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001176 def test_get_extensions(self):
1177 """
1178 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1179 extensions added to this X509 request.
1180 """
1181 request = X509Req()
1182 exts = request.get_extensions()
1183 self.assertEqual(exts, [])
1184 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001185 X509Extension(b('basicConstraints'), True, b('CA:true')),
1186 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001187 exts = request.get_extensions()
1188 self.assertEqual(len(exts), 2)
1189 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1190 self.assertEqual(exts[0].get_critical(), 1)
1191 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1192 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1193 self.assertEqual(exts[1].get_critical(), 0)
1194 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001195
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001196 def test_add_extensions_wrong_args(self):
1197 """
Alex Gaynor31287502015-09-05 16:11:27 -04001198 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1199 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1200 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1201 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001202 """
1203 request = X509Req()
1204 self.assertRaises(TypeError, request.add_extensions)
1205 self.assertRaises(TypeError, request.add_extensions, object())
1206 self.assertRaises(ValueError, request.add_extensions, [object()])
1207 self.assertRaises(TypeError, request.add_extensions, [], None)
1208
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001209 def test_verify_wrong_args(self):
1210 """
1211 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1212 arguments or more than one argument or if passed anything other than a
1213 :py:obj:`PKey` instance as its single argument.
1214 """
1215 request = X509Req()
1216 self.assertRaises(TypeError, request.verify)
1217 self.assertRaises(TypeError, request.verify, object())
1218 self.assertRaises(TypeError, request.verify, PKey(), object())
1219
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001220 def test_verify_uninitialized_key(self):
1221 """
Alex Gaynor31287502015-09-05 16:11:27 -04001222 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1223 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001224 """
1225 request = X509Req()
1226 pkey = PKey()
1227 self.assertRaises(Error, request.verify, pkey)
1228
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001229 def test_verify_wrong_key(self):
1230 """
Alex Gaynor31287502015-09-05 16:11:27 -04001231 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1232 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1233 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001234 """
1235 request = X509Req()
1236 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001237 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001238 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1239 self.assertRaises(Error, request.verify, another_pkey)
1240
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001241 def test_verify_success(self):
1242 """
1243 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001244 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1245 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001246 """
1247 request = X509Req()
1248 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001249 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001250 self.assertEqual(True, request.verify(pkey))
1251
1252
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001253class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001254 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001255 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001256 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001257 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001258
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001259 extpem = """
1260-----BEGIN CERTIFICATE-----
1261MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1262BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1263eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1264MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1265aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1266hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1267Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1268zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1269hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1270TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
127103HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1272MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1273b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1274MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1275uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1276WpOdIpB8KksUTCzV591Nr1wd
1277-----END CERTIFICATE-----
1278 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001279
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001280 def signable(self):
1281 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001282 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001283 """
1284 return X509()
1285
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001286 def test_type(self):
1287 """
Alex Gaynor31287502015-09-05 16:11:27 -04001288 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1289 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001290 """
1291 self.assertIdentical(X509, X509Type)
1292 self.assertConsistentType(X509, 'X509')
1293
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001294 def test_construction(self):
1295 """
Alex Gaynor31287502015-09-05 16:11:27 -04001296 :py:obj:`X509` takes no arguments and returns an instance of
1297 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001298 """
1299 certificate = X509()
1300 self.assertTrue(
1301 isinstance(certificate, X509Type),
1302 "%r is of type %r, should be %r" % (certificate,
1303 type(certificate),
1304 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001305 self.assertEqual(type(X509Type).__name__, 'type')
1306 self.assertEqual(type(certificate).__name__, 'X509')
1307 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001308 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001309
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001310 def test_get_version_wrong_args(self):
1311 """
Alex Gaynor31287502015-09-05 16:11:27 -04001312 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1313 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001314 """
1315 cert = X509()
1316 self.assertRaises(TypeError, cert.get_version, None)
1317
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001318 def test_set_version_wrong_args(self):
1319 """
Alex Gaynor31287502015-09-05 16:11:27 -04001320 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1321 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001322 """
1323 cert = X509()
1324 self.assertRaises(TypeError, cert.set_version)
1325 self.assertRaises(TypeError, cert.set_version, None)
1326 self.assertRaises(TypeError, cert.set_version, 1, None)
1327
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001328 def test_version(self):
1329 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001330 :py:obj:`X509.set_version` sets the certificate version number.
1331 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001332 """
1333 cert = X509()
1334 cert.set_version(1234)
1335 self.assertEquals(cert.get_version(), 1234)
1336
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001337 def test_get_serial_number_wrong_args(self):
1338 """
Alex Gaynor31287502015-09-05 16:11:27 -04001339 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1340 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001341 """
1342 cert = X509()
1343 self.assertRaises(TypeError, cert.get_serial_number, None)
1344
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001345 def test_serial_number(self):
1346 """
Alex Gaynor31287502015-09-05 16:11:27 -04001347 The serial number of an :py:obj:`X509Type` can be retrieved and
1348 modified with :py:obj:`X509Type.get_serial_number` and
1349 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001350 """
1351 certificate = X509()
1352 self.assertRaises(TypeError, certificate.set_serial_number)
1353 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1354 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1355 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1356 self.assertEqual(certificate.get_serial_number(), 0)
1357 certificate.set_serial_number(1)
1358 self.assertEqual(certificate.get_serial_number(), 1)
1359 certificate.set_serial_number(2 ** 32 + 1)
1360 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1361 certificate.set_serial_number(2 ** 64 + 1)
1362 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001363 certificate.set_serial_number(2 ** 128 + 1)
1364 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1365
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001366 def _setBoundTest(self, which):
1367 """
Alex Gaynor31287502015-09-05 16:11:27 -04001368 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1369 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1370 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001371 """
1372 certificate = X509()
1373 set = getattr(certificate, 'set_not' + which)
1374 get = getattr(certificate, 'get_not' + which)
1375
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001376 # Starts with no value.
1377 self.assertEqual(get(), None)
1378
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001379 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001380 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001381 set(when)
1382 self.assertEqual(get(), when)
1383
1384 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001385 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001386 set(when)
1387 self.assertEqual(get(), when)
1388
1389 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001390 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001391 set(when)
1392 self.assertEqual(get(), when)
1393
1394 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001395 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001396
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001397 # The wrong number of arguments results in a TypeError.
1398 self.assertRaises(TypeError, set)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001399 self.assertRaises(TypeError, set, b("20040203040506Z"), b("20040203040506Z"))
1400 self.assertRaises(TypeError, get, b("foo bar"))
1401
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001402 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001403
1404 def test_set_notBefore(self):
1405 """
Alex Gaynor31287502015-09-05 16:11:27 -04001406 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1407 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1408 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001409 """
1410 self._setBoundTest("Before")
1411
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001412 def test_set_notAfter(self):
1413 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001414 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001415 GENERALIZEDTIME and sets the end of the certificate's validity period
1416 to it.
1417 """
1418 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001419
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001420 def test_get_notBefore(self):
1421 """
Alex Gaynor31287502015-09-05 16:11:27 -04001422 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1423 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001424 internally.
1425 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001426 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001427 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001428
Rick Dean38a05c82009-07-18 01:41:30 -05001429 def test_get_notAfter(self):
1430 """
Alex Gaynor31287502015-09-05 16:11:27 -04001431 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1432 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001433 internally.
1434 """
1435 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001436 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001437
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001438 def test_gmtime_adj_notBefore_wrong_args(self):
1439 """
Alex Gaynor31287502015-09-05 16:11:27 -04001440 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1441 called with the wrong number of arguments or a non-:py:obj:`int`
1442 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001443 """
1444 cert = X509()
1445 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1446 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1447 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1448
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001449 def test_gmtime_adj_notBefore(self):
1450 """
Alex Gaynor31287502015-09-05 16:11:27 -04001451 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1452 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001453 """
1454 cert = load_certificate(FILETYPE_PEM, self.pemData)
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001455 not_before_min = datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001456 cert.gmtime_adj_notBefore(100)
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001457 not_before = datetime.strptime(cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ")
1458 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1459 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001460
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001461 def test_gmtime_adj_notAfter_wrong_args(self):
1462 """
Alex Gaynor31287502015-09-05 16:11:27 -04001463 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1464 called with the wrong number of arguments or a non-:py:obj:`int`
1465 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001466 """
1467 cert = X509()
1468 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1469 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1470 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1471
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001472 def test_gmtime_adj_notAfter(self):
1473 """
Alex Gaynor31287502015-09-05 16:11:27 -04001474 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1475 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001476 """
1477 cert = load_certificate(FILETYPE_PEM, self.pemData)
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001478 not_after_min = datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001479 cert.gmtime_adj_notAfter(100)
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001480 not_after = datetime.strptime(cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ")
1481 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1482 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001483
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001484 def test_has_expired_wrong_args(self):
1485 """
Alex Gaynor31287502015-09-05 16:11:27 -04001486 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1487 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001488 """
1489 cert = X509()
1490 self.assertRaises(TypeError, cert.has_expired, None)
1491
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001492 def test_has_expired(self):
1493 """
Alex Gaynor31287502015-09-05 16:11:27 -04001494 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1495 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001496 """
1497 cert = X509()
1498 cert.gmtime_adj_notAfter(-1)
1499 self.assertTrue(cert.has_expired())
1500
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001501 def test_has_not_expired(self):
1502 """
Alex Gaynor31287502015-09-05 16:11:27 -04001503 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1504 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001505 """
1506 cert = X509()
1507 cert.gmtime_adj_notAfter(2)
1508 self.assertFalse(cert.has_expired())
1509
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001510 def test_root_has_not_expired(self):
1511 """
Alex Gaynor31287502015-09-05 16:11:27 -04001512 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1513 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001514 """
1515 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1516 self.assertFalse(cert.has_expired())
1517
Rick Dean38a05c82009-07-18 01:41:30 -05001518 def test_digest(self):
1519 """
Alex Gaynor31287502015-09-05 16:11:27 -04001520 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1521 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001522 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001523 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001524 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001525 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1526 # actually matters to the assertion (ie, another arbitrary, good
1527 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001528 # Digest verified with the command:
1529 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001530 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001531 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001532
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001533 def _extcert(self, pkey, extensions):
1534 cert = X509()
1535 cert.set_pubkey(pkey)
1536 cert.get_subject().commonName = "Unit Tests"
1537 cert.get_issuer().commonName = "Unit Tests"
1538 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1539 cert.set_notBefore(when)
1540 cert.set_notAfter(when)
1541
1542 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001543 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001544 return load_certificate(
1545 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1546
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001547 def test_extension_count(self):
1548 """
Alex Gaynor31287502015-09-05 16:11:27 -04001549 :py:obj:`X509.get_extension_count` returns the number of extensions
1550 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001551 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001552 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001553 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1554 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001555 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001556 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001557
1558 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001559 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001560 self.assertEqual(c.get_extension_count(), 0)
1561
1562 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001563 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001564 self.assertEqual(c.get_extension_count(), 1)
1565
1566 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001567 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001568 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001569
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001570 def test_get_extension(self):
1571 """
Alex Gaynor31287502015-09-05 16:11:27 -04001572 :py:obj:`X509.get_extension` takes an integer and returns an
1573 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001574 """
1575 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001576 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1577 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001578 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001579 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001580
1581 cert = self._extcert(pkey, [ca, key, subjectAltName])
1582
1583 ext = cert.get_extension(0)
1584 self.assertTrue(isinstance(ext, X509Extension))
1585 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001586 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001587
1588 ext = cert.get_extension(1)
1589 self.assertTrue(isinstance(ext, X509Extension))
1590 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001591 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001592
1593 ext = cert.get_extension(2)
1594 self.assertTrue(isinstance(ext, X509Extension))
1595 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001596 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001597
1598 self.assertRaises(IndexError, cert.get_extension, -1)
1599 self.assertRaises(IndexError, cert.get_extension, 4)
1600 self.assertRaises(TypeError, cert.get_extension, "hello")
1601
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001602 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001603 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001604 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001605 bytes and this value is reflected in the string representation of the
1606 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001607 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001608 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001609
1610 ext = cert.get_extension(3)
1611 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001612 self.assertEqual(
1613 b("DNS:altnull.python.org\x00example.com, "
1614 "email:null@python.org\x00user@example.org, "
1615 "URI:http://null.python.org\x00http://example.org, "
1616 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1617 b(str(ext)))
1618
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001619 def test_invalid_digest_algorithm(self):
1620 """
Alex Gaynor31287502015-09-05 16:11:27 -04001621 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1622 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001623 """
1624 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001625 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001626
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001627 def test_get_subject_wrong_args(self):
1628 """
Alex Gaynor31287502015-09-05 16:11:27 -04001629 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1630 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001631 """
1632 cert = X509()
1633 self.assertRaises(TypeError, cert.get_subject, None)
1634
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001635 def test_get_subject(self):
1636 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001637 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001638 """
1639 cert = load_certificate(FILETYPE_PEM, self.pemData)
1640 subj = cert.get_subject()
1641 self.assertTrue(isinstance(subj, X509Name))
1642 self.assertEquals(
1643 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001644 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1645 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001646
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001647 def test_set_subject_wrong_args(self):
1648 """
Alex Gaynor31287502015-09-05 16:11:27 -04001649 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1650 the wrong number of arguments or an argument not of type
1651 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001652 """
1653 cert = X509()
1654 self.assertRaises(TypeError, cert.set_subject)
1655 self.assertRaises(TypeError, cert.set_subject, None)
1656 self.assertRaises(TypeError, cert.set_subject, cert.get_subject(), None)
1657
1658
1659 def test_set_subject(self):
1660 """
Alex Gaynor31287502015-09-05 16:11:27 -04001661 :py:obj:`X509.set_subject` changes the subject of the certificate to
1662 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001663 """
1664 cert = X509()
1665 name = cert.get_subject()
1666 name.C = 'AU'
1667 name.O = 'Unit Tests'
1668 cert.set_subject(name)
1669 self.assertEquals(
1670 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001671 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001672
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001673 def test_get_issuer_wrong_args(self):
1674 """
Alex Gaynor31287502015-09-05 16:11:27 -04001675 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1676 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001677 """
1678 cert = X509()
1679 self.assertRaises(TypeError, cert.get_issuer, None)
1680
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001681 def test_get_issuer(self):
1682 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001683 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001684 """
1685 cert = load_certificate(FILETYPE_PEM, self.pemData)
1686 subj = cert.get_issuer()
1687 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001688 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001689 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001690 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001691 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1692 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001693
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001694 def test_set_issuer_wrong_args(self):
1695 """
Alex Gaynor31287502015-09-05 16:11:27 -04001696 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1697 the wrong number of arguments or an argument not of type
1698 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001699 """
1700 cert = X509()
1701 self.assertRaises(TypeError, cert.set_issuer)
1702 self.assertRaises(TypeError, cert.set_issuer, None)
1703 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1704
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001705 def test_set_issuer(self):
1706 """
Alex Gaynor31287502015-09-05 16:11:27 -04001707 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1708 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001709 """
1710 cert = X509()
1711 name = cert.get_issuer()
1712 name.C = 'AU'
1713 name.O = 'Unit Tests'
1714 cert.set_issuer(name)
1715 self.assertEquals(
1716 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001717 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001718
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001719 def test_get_pubkey_uninitialized(self):
1720 """
Alex Gaynor31287502015-09-05 16:11:27 -04001721 When called on a certificate with no public key,
1722 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001723 """
1724 cert = X509()
1725 self.assertRaises(Error, cert.get_pubkey)
1726
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001727 def test_subject_name_hash_wrong_args(self):
1728 """
Alex Gaynor31287502015-09-05 16:11:27 -04001729 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1730 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001731 """
1732 cert = X509()
1733 self.assertRaises(TypeError, cert.subject_name_hash, None)
1734
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001735 def test_subject_name_hash(self):
1736 """
Alex Gaynor31287502015-09-05 16:11:27 -04001737 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1738 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001739 """
1740 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001741 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001742 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001743 [3350047874, # OpenSSL 0.9.8, MD5
1744 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001745 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001746
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001747 def test_get_signature_algorithm(self):
1748 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001749 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001750 the algorithm used to sign the certificate.
1751 """
1752 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001753 self.assertEqual(
1754 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001755
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001756 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001757 """
Alex Gaynor31287502015-09-05 16:11:27 -04001758 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1759 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001760 """
1761 # This certificate has been modified to indicate a bogus OID in the
1762 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001763 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001764-----BEGIN CERTIFICATE-----
1765MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1766EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1767cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1768MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1769EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1770CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1771AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1772+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1773hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1774BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1775FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1776dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1777aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1778MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1779jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1780PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1781tgI5
1782-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001783""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001784 cert = load_certificate(FILETYPE_PEM, certPEM)
1785 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001786
1787
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001788class X509StoreTests(TestCase):
1789 """
1790 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1791 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001792
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001793 def test_type(self):
1794 """
1795 :py:obj:`X509StoreType` is a type object.
1796 """
1797 self.assertIdentical(X509Store, X509StoreType)
1798 self.assertConsistentType(X509Store, 'X509Store')
1799
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001800 def test_add_cert_wrong_args(self):
1801 store = X509Store()
1802 self.assertRaises(TypeError, store.add_cert)
1803 self.assertRaises(TypeError, store.add_cert, object())
1804 self.assertRaises(TypeError, store.add_cert, X509(), object())
1805
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001806 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001807 """
1808 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1809 certificate store.
1810 """
1811 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001812 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001813 store.add_cert(cert)
1814
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001815 def test_add_cert_rejects_duplicate(self):
1816 """
Alex Gaynor31287502015-09-05 16:11:27 -04001817 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1818 an attempt is made to add the same certificate to the store more than
1819 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001820 """
1821 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1822 store = X509Store()
1823 store.add_cert(cert)
1824 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001825
1826
Rick Dean623ee362009-07-17 12:22:16 -05001827class PKCS12Tests(TestCase):
1828 """
Alex Gaynor31287502015-09-05 16:11:27 -04001829 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1830 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001831 """
1832 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1833
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001834 def test_type(self):
1835 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001836 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001837 """
1838 self.assertIdentical(PKCS12, PKCS12Type)
1839 self.assertConsistentType(PKCS12, 'PKCS12')
1840
Rick Deanf94096c2009-07-18 14:23:06 -05001841 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001842 """
Alex Gaynor31287502015-09-05 16:11:27 -04001843 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1844 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001845 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001846 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001847 self.assertEqual(None, p12.get_certificate())
1848 self.assertEqual(None, p12.get_privatekey())
1849 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001850 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001851
1852 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001853 """
Alex Gaynor31287502015-09-05 16:11:27 -04001854 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1855 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1856 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1857 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001858 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001859 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001860 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001861 self.assertRaises(TypeError, p12.set_certificate, PKey())
1862 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001863 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001864 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1865 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001866 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1867 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1868 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001869 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001870 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1871 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001872
1873 def test_key_only(self):
1874 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001875 A :py:obj:`PKCS12` with only a private key can be exported using
1876 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001877 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001878 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001879 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001880 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001881 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05001882 self.assertEqual(None, p12.get_certificate())
1883 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001884 try:
1885 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1886 except Error:
1887 # Some versions of OpenSSL will throw an exception
1888 # for this nearly useless PKCS12 we tried to generate:
1889 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1890 return
Rick Dean623ee362009-07-17 12:22:16 -05001891 p12 = load_pkcs12(dumped_p12, passwd)
1892 self.assertEqual(None, p12.get_ca_certificates())
1893 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001894
1895 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1896 # future this will be improved.
1897 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05001898
1899 def test_cert_only(self):
1900 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001901 A :py:obj:`PKCS12` with only a certificate can be exported using
1902 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001903 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001904 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001905 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001906 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001907 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05001908 self.assertEqual(cert, p12.get_certificate())
1909 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001910 try:
1911 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1912 except Error:
1913 # Some versions of OpenSSL will throw an exception
1914 # for this nearly useless PKCS12 we tried to generate:
1915 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1916 return
Rick Dean623ee362009-07-17 12:22:16 -05001917 p12 = load_pkcs12(dumped_p12, passwd)
1918 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001919
1920 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
1921 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1922
1923 # Oh ho. It puts the certificate into the ca certificates list, in
1924 # fact. Totally bogus, I would think. Nevertheless, let's exploit
1925 # that to check to see if it reconstructed the certificate we expected
1926 # it to. At some point, hopefully this will change so that
1927 # p12.get_certificate() is actually what returns the loaded
1928 # certificate.
1929 self.assertEqual(
1930 cleartextCertificatePEM,
1931 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05001932
Alex Gaynor31287502015-09-05 16:11:27 -04001933 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
1934 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05001935 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001936 Generate a PKCS12 object with components from PEM. Verify that the set
1937 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05001938 """
Rick Deanf94096c2009-07-18 14:23:06 -05001939 p12 = PKCS12()
1940 if cert_pem:
1941 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1942 self.assertEqual(ret, None)
1943 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001944 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05001945 self.assertEqual(ret, None)
1946 if ca_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001947 ret = p12.set_ca_certificates((load_certificate(FILETYPE_PEM, ca_pem),))
Rick Deanf94096c2009-07-18 14:23:06 -05001948 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001949 if friendly_name:
1950 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05001951 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05001952 return p12
1953
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001954 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001955 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05001956 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001957 Use openssl program to confirm three components are recoverable from a
1958 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05001959 """
1960 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001961 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001962 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
1963 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001964 self.assertEqual(recovered_key[-len(key):], key)
1965 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001966 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001967 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
1968 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001969 self.assertEqual(recovered_cert[-len(cert):], cert)
1970 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001971 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001972 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
1973 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001974 self.assertEqual(recovered_cert[-len(ca):], ca)
1975
Stephen Holsapple38482622014-04-05 20:29:34 -07001976 def verify_pkcs12_container(self, p12):
1977 """
1978 Verify that the PKCS#12 container contains the correct client
1979 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04001980
1981 :param p12: The PKCS12 instance to verify.
1982 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07001983 """
1984 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
1985 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04001986 self.assertEqual(
1987 (client_cert_pem, client_key_pem, None),
1988 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07001989
Rick Deanf94096c2009-07-18 14:23:06 -05001990 def test_load_pkcs12(self):
1991 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001992 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09001993 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05001994 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001995 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05001996 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001997 p12_str = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001998 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:" + passwd)
Stephen Holsapple38482622014-04-05 20:29:34 -07001999 p12 = load_pkcs12(p12_str, passphrase=passwd)
2000 self.verify_pkcs12_container(p12)
2001
Abraham Martinc5484ba2015-03-25 15:33:05 +00002002 def test_load_pkcs12_text_passphrase(self):
2003 """
2004 A PKCS12 string generated using the openssl command line can be loaded
2005 with :py:obj:`load_pkcs12` and its components extracted and examined.
2006 Using text as passphrase instead of bytes. DeprecationWarning expected.
2007 """
2008 pem = client_key_pem + client_cert_pem
2009 passwd = b"whatever"
2010 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2011 b"-passout", b"pass:" + passwd)
2012 with catch_warnings(record=True) as w:
2013 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002014 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002015
2016 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002017 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002018 WARNING_TYPE_EXPECTED
2019 ),
2020 str(w[-1].message)
2021 )
2022 self.assertIs(w[-1].category, DeprecationWarning)
2023
Abraham Martinc5484ba2015-03-25 15:33:05 +00002024 self.verify_pkcs12_container(p12)
2025
Stephen Holsapple38482622014-04-05 20:29:34 -07002026 def test_load_pkcs12_no_passphrase(self):
2027 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002028 A PKCS12 string generated using openssl command line can be loaded with
2029 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2030 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002031 """
2032 pem = client_key_pem + client_cert_pem
2033 p12_str = _runopenssl(
2034 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2035 p12 = load_pkcs12(p12_str)
2036 self.verify_pkcs12_container(p12)
2037
Stephen Holsapple38482622014-04-05 20:29:34 -07002038 def _dump_and_load(self, dump_passphrase, load_passphrase):
2039 """
2040 A helper method to dump and load a PKCS12 object.
2041 """
2042 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2043 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2044 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2045
Stephen Holsapple38482622014-04-05 20:29:34 -07002046 def test_load_pkcs12_null_passphrase_load_empty(self):
2047 """
2048 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002049 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002050 extracted and examined.
2051 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002052 self.verify_pkcs12_container(
2053 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002054
Stephen Holsapple38482622014-04-05 20:29:34 -07002055 def test_load_pkcs12_null_passphrase_load_null(self):
2056 """
2057 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002058 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002059 extracted and examined.
2060 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002061 self.verify_pkcs12_container(
2062 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002063
Stephen Holsapple38482622014-04-05 20:29:34 -07002064 def test_load_pkcs12_empty_passphrase_load_empty(self):
2065 """
2066 A PKCS12 string can be dumped with an empty 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=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002072
Stephen Holsapple38482622014-04-05 20:29:34 -07002073 def test_load_pkcs12_empty_passphrase_load_null(self):
2074 """
2075 A PKCS12 string can be dumped with an empty 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=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002081
Rick Deanee568302009-07-24 09:56:29 -05002082 def test_load_pkcs12_garbage(self):
2083 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002084 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed a string
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002085 which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002086 """
2087 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002088 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002089 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2090 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002091
Rick Deanf94096c2009-07-18 14:23:06 -05002092 def test_replace(self):
2093 """
Alex Gaynor31287502015-09-05 16:11:27 -04002094 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2095 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002096 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002097 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002098 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2099 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2100 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002101 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002102 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002103 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002104 self.assertEqual(1, len(p12.get_ca_certificates()))
2105 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002106 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002107 self.assertEqual(2, len(p12.get_ca_certificates()))
2108 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2109 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2110
Rick Deanf94096c2009-07-18 14:23:06 -05002111 def test_friendly_name(self):
2112 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002113 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor31287502015-09-05 16:11:27 -04002114 :py:obj:`PKCS12.get_friendlyname` and :py:obj:`PKCS12_set_friendlyname`,
2115 and a :py:obj:`PKCS12` with a friendly name set can be dumped with
2116 :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002117 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002118 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002119 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002120 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002121 p12.set_friendlyname(friendly_name)
2122 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002123 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002124 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002125 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002126 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002127 # We would use the openssl program to confirm the friendly
2128 # name, but it is not possible. The pkcs12 command
2129 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002130 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002131 self.check_recovery(
2132 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2133 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002134
Rick Deanf94096c2009-07-18 14:23:06 -05002135 def test_various_empty_passphrases(self):
2136 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002137 Test that missing, None, and '' passphrases are identical for PKCS12
2138 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002139 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002140 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002141 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002142 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2143 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2144 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2145 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2146 self.check_recovery(
2147 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2148 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002149
Rick Deanf94096c2009-07-18 14:23:06 -05002150 def test_removing_ca_cert(self):
2151 """
Alex Gaynor31287502015-09-05 16:11:27 -04002152 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2153 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002154 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002155 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2156 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002157 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002158
Rick Deanf94096c2009-07-18 14:23:06 -05002159 def test_export_without_mac(self):
2160 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002161 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002162 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002163 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002164 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002165 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002166 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002167 self.check_recovery(
2168 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002169 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002170
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002171 def test_load_without_mac(self):
2172 """
2173 Loading a PKCS12 without a MAC does something other than crash.
2174 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002175 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002176 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2177 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002178 try:
2179 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2180 # The person who generated this PCKS12 should be flogged,
2181 # or better yet we should have a means to determine
2182 # whether a PCKS12 had a MAC that was verified.
2183 # Anyway, libopenssl chooses to allow it, so the
2184 # pyopenssl binding does as well.
2185 self.assertTrue(isinstance(recovered_p12, PKCS12))
2186 except Error:
2187 # Failing here with an exception is preferred as some openssl
2188 # versions do.
2189 pass
Rick Dean623ee362009-07-17 12:22:16 -05002190
Rick Dean25bcc1f2009-07-20 11:53:13 -05002191 def test_zero_len_list_for_ca(self):
2192 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002193 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002194 """
2195 passwd = 'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002196 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -08002197 # p12.set_ca_certificates([])
2198 # self.assertEqual((), p12.get_ca_certificates())
2199 # dumped_p12 = p12.export(passphrase=passwd, iter=3)
2200 # self.check_recovery(
2201 # dumped_p12, key=server_key_pem, cert=server_cert_pem,
2202 # passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002203
Rick Deanf94096c2009-07-18 14:23:06 -05002204 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002205 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002206 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002207 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002208 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002209 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002210 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002211 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002212
Abraham Martinc5484ba2015-03-25 15:33:05 +00002213 def test_export_without_bytes(self):
2214 """
2215 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2216 """
2217 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2218
2219 with catch_warnings(record=True) as w:
2220 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002221 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002222 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002223 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002224 WARNING_TYPE_EXPECTED
2225 ),
2226 str(w[-1].message)
2227 )
2228 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002229 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002230 dumped_p12,
2231 key=server_key_pem,
2232 cert=server_cert_pem,
2233 passwd=b"randomtext"
2234 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002235
Rick Deanf94096c2009-07-18 14:23:06 -05002236 def test_key_cert_mismatch(self):
2237 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002238 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002239 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002240 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002241 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2242 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002243
2244
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002245# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002246_cmdLineQuoteRe = re.compile(br'(\\*)"')
2247_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002248
2249
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002250def cmdLineQuote(s):
2251 """
2252 Internal method for quoting a single command-line argument.
2253
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002254 See http://www.perlmonks.org/?node_id=764004
2255
Jonathan Ballet648875f2011-07-16 14:14:58 +09002256 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002257 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002258 cmd.exe-style quoting
2259
Jonathan Ballet648875f2011-07-16 14:14:58 +09002260 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002261 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002262 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002263 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2264 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002265
2266
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002267def quoteArguments(arguments):
2268 """
2269 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002270 a similar API. This allows the list passed to
2271 :py:obj:`reactor.spawnProcess` to match the child process's
2272 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002273
Jonathan Ballet648875f2011-07-16 14:14:58 +09002274 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002275 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002276
Jonathan Ballet648875f2011-07-16 14:14:58 +09002277 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002278 :return: A space-delimited string containing quoted versions of
2279 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002280 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002281 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002282
2283
Rick Dean4c9ad612009-07-17 15:05:22 -05002284def _runopenssl(pem, *args):
2285 """
2286 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002287 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002288 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002289 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002290 command = b"openssl " + b" ".join([
2291 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2292 for arg in args])
Rick Dean55d1ce62009-08-13 17:40:24 -05002293 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002294 command = b"openssl " + quoteArguments(args)
2295 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002296 proc.stdin.write(pem)
2297 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002298 output = proc.stdout.read()
2299 proc.stdout.close()
2300 proc.wait()
2301 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002302
2303
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002304class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002305 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002306 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002307 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002308
2309 def test_load_privatekey_invalid_format(self):
2310 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002311 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2312 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002313 """
2314 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2315
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002316 def test_load_privatekey_invalid_passphrase_type(self):
2317 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002318 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2319 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002320 """
2321 self.assertRaises(
2322 TypeError,
2323 load_privatekey,
2324 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2325
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002326 def test_load_privatekey_wrong_args(self):
2327 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002328 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2329 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002330 """
2331 self.assertRaises(TypeError, load_privatekey)
2332
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002333 def test_load_privatekey_wrongPassphrase(self):
2334 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002335 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2336 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002337 """
2338 self.assertRaises(
2339 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002340 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002341
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002342 def test_load_privatekey_passphraseWrongType(self):
2343 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002344 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2345 a passphrase with a private key encoded in a format, that doesn't
2346 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002347 """
2348 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2349 blob = dump_privatekey(FILETYPE_ASN1, key)
2350 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002351 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002352
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002353 def test_load_privatekey_passphrase(self):
2354 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002355 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2356 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002357 """
2358 key = load_privatekey(
2359 FILETYPE_PEM, encryptedPrivateKeyPEM,
2360 encryptedPrivateKeyPEMPassphrase)
2361 self.assertTrue(isinstance(key, PKeyType))
2362
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002363 def test_load_privatekey_passphrase_exception(self):
2364 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002365 If the passphrase callback raises an exception, that exception is
2366 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002367 """
2368 def cb(ignored):
2369 raise ArithmeticError
2370
Alex Gaynor791212d2015-09-05 15:46:08 -04002371 with pytest.raises(ArithmeticError):
2372 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002373
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002374 def test_load_privatekey_wrongPassphraseCallback(self):
2375 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002376 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2377 is passed an encrypted PEM and a passphrase callback which returns an
2378 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002379 """
2380 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002381
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002382 def cb(*a):
2383 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002384 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002385 self.assertRaises(
2386 Error,
2387 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2388 self.assertTrue(called)
2389
2390 def test_load_privatekey_passphraseCallback(self):
2391 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002392 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2393 encrypted PEM string if given a passphrase callback which returns the
2394 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002395 """
2396 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002397
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002398 def cb(writing):
2399 called.append(writing)
2400 return encryptedPrivateKeyPEMPassphrase
2401 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2402 self.assertTrue(isinstance(key, PKeyType))
2403 self.assertEqual(called, [False])
2404
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002405 def test_load_privatekey_passphrase_wrong_return_type(self):
2406 """
2407 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2408 callback returns something other than a byte string.
2409 """
2410 self.assertRaises(
2411 ValueError,
2412 load_privatekey,
2413 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2414
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002415 def test_dump_privatekey_wrong_args(self):
2416 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002417 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2418 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002419 """
2420 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002421 # If cipher name is given, password is required.
2422 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002423 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002424
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002425 def test_dump_privatekey_unknown_cipher(self):
2426 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002427 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2428 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002429 """
2430 key = PKey()
2431 key.generate_key(TYPE_RSA, 512)
2432 self.assertRaises(
2433 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002434 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002435
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002436 def test_dump_privatekey_invalid_passphrase_type(self):
2437 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002438 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2439 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002440 """
2441 key = PKey()
2442 key.generate_key(TYPE_RSA, 512)
2443 self.assertRaises(
2444 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002445 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002446
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002447 def test_dump_privatekey_invalid_filetype(self):
2448 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002449 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2450 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002451 """
2452 key = PKey()
2453 key.generate_key(TYPE_RSA, 512)
2454 self.assertRaises(ValueError, dump_privatekey, 100, key)
2455
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002456 def test_load_privatekey_passphraseCallbackLength(self):
2457 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002458 :py:obj:`crypto.load_privatekey` should raise an error when the
2459 passphrase provided by the callback is too long, not silently truncate
2460 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002461 """
2462 def cb(ignored):
2463 return "a" * 1025
2464
Alex Gaynor791212d2015-09-05 15:46:08 -04002465 with pytest.raises(ValueError):
2466 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002467
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002468 def test_dump_privatekey_passphrase(self):
2469 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002470 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2471 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002472 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002473 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002474 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002475 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2476 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002477 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2478 self.assertTrue(isinstance(loadedKey, PKeyType))
2479 self.assertEqual(loadedKey.type(), key.type())
2480 self.assertEqual(loadedKey.bits(), key.bits())
2481
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002482 def test_dump_privatekey_passphraseWrongType(self):
2483 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002484 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2485 a passphrase with a private key encoded in a format, that doesn't
2486 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002487 """
2488 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002489 with pytest.raises(ValueError):
2490 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002491
Rick Dean5b7b6372009-04-01 11:34:06 -05002492 def test_dump_certificate(self):
2493 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002494 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002495 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002496 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002497 cert = load_certificate(FILETYPE_PEM, pemData)
2498 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2499 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2500 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002501 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002502 self.assertEqual(dumped_der, good_der)
2503 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2504 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2505 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2506 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002507 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002508 self.assertEqual(dumped_text, good_text)
2509
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002510 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002511 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002512 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002513 """
2514 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002515 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002516 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2517 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002518
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002519 def test_dump_privatekey_asn1(self):
2520 """
2521 :py:obj:`dump_privatekey` writes a DER
2522 """
2523 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2524 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2525
Rick Dean5b7b6372009-04-01 11:34:06 -05002526 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002527 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002528 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002529 self.assertEqual(dumped_der, good_der)
2530 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2531 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2532 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002533
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002534 def test_dump_privatekey_text(self):
2535 """
2536 :py:obj:`dump_privatekey` writes a text
2537 """
2538 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2539 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2540
Rick Dean5b7b6372009-04-01 11:34:06 -05002541 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002542 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002543 self.assertEqual(dumped_text, good_text)
2544
2545 def test_dump_certificate_request(self):
2546 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002547 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002548 """
Alex Gaynor31287502015-09-05 16:11:27 -04002549 req = load_certificate_request(
2550 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002551 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2552 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2553 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002554 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002555 self.assertEqual(dumped_der, good_der)
2556 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2557 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2558 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2559 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002560 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002561 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002562 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002563
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002564 def test_dump_privatekey_passphraseCallback(self):
2565 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002566 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2567 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002568 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002569 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002570 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002571
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002572 def cb(writing):
2573 called.append(writing)
2574 return passphrase
2575 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002576 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2577 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002578 self.assertEqual(called, [True])
2579 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2580 self.assertTrue(isinstance(loadedKey, PKeyType))
2581 self.assertEqual(loadedKey.type(), key.type())
2582 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002583
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002584 def test_dump_privatekey_passphrase_exception(self):
2585 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002586 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002587 by the passphrase callback.
2588 """
2589 def cb(ignored):
2590 raise ArithmeticError
2591
2592 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2593 self.assertRaises(ArithmeticError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002594 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002595
2596
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002597 def test_dump_privatekey_passphraseCallbackLength(self):
2598 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002599 :py:obj:`crypto.dump_privatekey` should raise an error when the
2600 passphrase provided by the callback is too long, not silently truncate
2601 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002602 """
2603 def cb(ignored):
2604 return "a" * 1025
2605
2606 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2607 self.assertRaises(ValueError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002608 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002609
2610
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002611 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002612 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002613 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2614 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002615 """
2616 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2617 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2618
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002619 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002620 """
2621 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2622 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2623 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002624 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2625 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2626
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002627 def test_load_pkcs7_data_invalid(self):
2628 """
2629 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2630 :py:obj:`Error` is raised.
2631 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002632 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002633
2634
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002635class LoadCertificateTests(TestCase):
2636 """
2637 Tests for :py:obj:`load_certificate_request`.
2638 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002639
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002640 def test_badFileType(self):
2641 """
2642 If the file type passed to :py:obj:`load_certificate_request` is
2643 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2644 :py:class:`ValueError` is raised.
2645 """
2646 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2647
2648
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002649class PKCS7Tests(TestCase):
2650 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002651 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002652 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002653
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002654 def test_type(self):
2655 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002656 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002657 """
2658 self.assertTrue(isinstance(PKCS7Type, type))
2659 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2660
2661 # XXX This doesn't currently work.
2662 # self.assertIdentical(PKCS7, PKCS7Type)
2663
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002664 # XXX Opposite results for all these following methods
2665
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002666 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002667 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002668 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2669 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002670 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002671 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2672 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2673
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002674 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002675 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002676 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2677 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002678 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002679 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2680 self.assertTrue(pkcs7.type_is_signed())
2681
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002682 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002683 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002684 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2685 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002686 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002687 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2688 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2689
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002690 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002691 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002692 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2693 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002694 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002695 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2696 self.assertFalse(pkcs7.type_is_enveloped())
2697
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002698 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002699 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002700 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2701 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002702 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002703 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2704 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2705
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002706 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002707 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002708 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2709 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002710 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002711 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2712 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2713
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002714 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002715 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002716 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2717 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002718 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002719 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2720 self.assertFalse(pkcs7.type_is_data())
2721
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002722 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002723 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002724 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2725 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002726 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002727 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2728 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2729
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002730 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002731 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002732 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2733 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002734 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002735 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2736 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2737
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002738 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002739 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002740 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2741 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002742 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002743 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002744 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002745
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002746 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002747 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002748 If an attribute other than one of the methods tested here is accessed
2749 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2750 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002751 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002752 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2753 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2754
2755
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002756class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002757 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002758 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002759 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002760
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002761 def signable(self):
2762 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002763 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002764 """
2765 return NetscapeSPKI()
2766
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002767 def test_type(self):
2768 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002769 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2770 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002771 """
2772 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2773 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2774
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002775 def test_construction(self):
2776 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002777 :py:obj:`NetscapeSPKI` returns an instance of
2778 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002779 """
2780 nspki = NetscapeSPKI()
2781 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2782
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002783 def test_invalid_attribute(self):
2784 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002785 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2786 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002787 """
2788 nspki = NetscapeSPKI()
2789 self.assertRaises(AttributeError, lambda: nspki.foo)
2790
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002791 def test_b64_encode(self):
2792 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002793 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2794 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002795 """
2796 nspki = NetscapeSPKI()
2797 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002798 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002799
2800
Rick Dean536ba022009-07-24 23:57:27 -05002801class RevokedTests(TestCase):
2802 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002803 Tests for :py:obj:`OpenSSL.crypto.Revoked`
Rick Dean536ba022009-07-24 23:57:27 -05002804 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002805
Rick Dean536ba022009-07-24 23:57:27 -05002806 def test_construction(self):
2807 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002808 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002809 that it is empty.
2810 """
2811 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002812 self.assertTrue(isinstance(revoked, Revoked))
2813 self.assertEquals(type(revoked), Revoked)
2814 self.assertEquals(revoked.get_serial(), b('00'))
2815 self.assertEquals(revoked.get_rev_date(), None)
2816 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05002817
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002818 def test_construction_wrong_args(self):
2819 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002820 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
2821 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002822 """
2823 self.assertRaises(TypeError, Revoked, None)
2824 self.assertRaises(TypeError, Revoked, 1)
2825 self.assertRaises(TypeError, Revoked, "foo")
2826
Rick Dean536ba022009-07-24 23:57:27 -05002827 def test_serial(self):
2828 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002829 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002830 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002831 with grace.
2832 """
2833 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002834 ret = revoked.set_serial(b('10b'))
2835 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002836 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002837 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05002838
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002839 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05002840 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002841 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05002842
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002843 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05002844 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002845 self.assertRaises(TypeError, revoked.get_serial, 1)
2846 self.assertRaises(TypeError, revoked.get_serial, None)
2847 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05002848
Rick Dean536ba022009-07-24 23:57:27 -05002849 def test_date(self):
2850 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002851 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002852 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002853 with grace.
2854 """
2855 revoked = Revoked()
2856 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002857 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05002858
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002859 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002860 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002861 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002862 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002863 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05002864
Rick Dean6385faf2009-07-26 00:07:47 -05002865 def test_reason(self):
2866 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002867 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002868 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05002869 as "set". Likewise, each reason of all_reasons() must work.
2870 """
2871 revoked = Revoked()
2872 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002873 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05002874 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002875 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05002876 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002877 self.assertEquals(
2878 reason.lower().replace(b(' '), b('')),
2879 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002880 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05002881
2882 revoked.set_reason(None)
2883 self.assertEqual(revoked.get_reason(), None)
2884
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002885 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05002886 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002887 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002888 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002889 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05002890 """
2891 revoked = Revoked()
2892 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04002893 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05002894
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002895 def test_get_reason_wrong_arguments(self):
2896 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002897 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
2898 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002899 """
2900 revoked = Revoked()
2901 self.assertRaises(TypeError, revoked.get_reason, None)
2902 self.assertRaises(TypeError, revoked.get_reason, 1)
2903 self.assertRaises(TypeError, revoked.get_reason, "foo")
2904
2905
Rick Dean536ba022009-07-24 23:57:27 -05002906class CRLTests(TestCase):
2907 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002908 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05002909 """
2910 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2911 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2912
2913 def test_construction(self):
2914 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002915 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002916 that it is empty
2917 """
2918 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04002919 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05002920 self.assertEqual(crl.get_revoked(), None)
2921
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05002922 def test_construction_wrong_args(self):
2923 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002924 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
2925 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05002926 """
2927 self.assertRaises(TypeError, CRL, 1)
2928 self.assertRaises(TypeError, CRL, "")
2929 self.assertRaises(TypeError, CRL, None)
2930
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002931 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05002932 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002933 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05002934 """
2935 crl = CRL()
2936 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002937 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002938 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002939 revoked.set_serial(b('3ab'))
2940 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05002941 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002942 return crl
Rick Dean536ba022009-07-24 23:57:27 -05002943
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002944 def test_export_pem(self):
2945 """
2946 If not passed a format, ``CRL.export`` returns a "PEM" format string
2947 representing a serial number, a revoked reason, and certificate issuer
2948 information.
2949 """
2950 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05002951 # PEM format
2952 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002953 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002954
2955 # These magic values are based on the way the CRL above was constructed
2956 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002957 text.index(b('Serial Number: 03AB'))
2958 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002959 text.index(
2960 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
2961 )
2962
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002963 def test_export_der(self):
2964 """
2965 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
2966 "DER" format string representing a serial number, a revoked reason, and
2967 certificate issuer information.
2968 """
2969 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05002970
2971 # DER format
2972 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002973 text = _runopenssl(
2974 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
2975 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002976 text.index(b('Serial Number: 03AB'))
2977 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002978 text.index(
2979 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
2980 )
2981
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002982 def test_export_text(self):
2983 """
2984 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
2985 text format string like the one produced by the openssl command line
2986 tool.
2987 """
2988 crl = self._get_crl()
2989
2990 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
2991 text = _runopenssl(
2992 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
2993 )
Rick Dean536ba022009-07-24 23:57:27 -05002994
2995 # text format
2996 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
2997 self.assertEqual(text, dumped_text)
2998
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002999 def test_export_custom_digest(self):
3000 """
3001 If passed the name of a digest function, ``CRL.export`` uses a
3002 signature algorithm based on that digest function.
3003 """
3004 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003005 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003006 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3007 text.index(b('Signature Algorithm: sha1'))
3008
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003009 def test_export_md5_digest(self):
3010 """
3011 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3012 not emit a deprecation warning.
3013 """
3014 crl = self._get_crl()
3015 with catch_warnings(record=True) as catcher:
3016 simplefilter("always")
3017 self.assertEqual(0, len(catcher))
3018 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3019 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3020 text.index(b('Signature Algorithm: md5'))
3021
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003022 def test_export_default_digest(self):
3023 """
3024 If not passed the name of a digest function, ``CRL.export`` uses a
3025 signature algorithm based on MD5 and emits a deprecation warning.
3026 """
3027 crl = self._get_crl()
3028 with catch_warnings(record=True) as catcher:
3029 simplefilter("always")
3030 dumped_crl = crl.export(self.cert, self.pkey)
3031 self.assertEqual(
3032 "The default message digest (md5) is deprecated. "
3033 "Pass the name of a message digest explicitly.",
3034 str(catcher[0].message),
3035 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003036 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3037 text.index(b('Signature Algorithm: md5'))
3038
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003039 def test_export_invalid(self):
3040 """
3041 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003042 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003043 """
3044 crl = CRL()
3045 self.assertRaises(Error, crl.export, X509(), PKey())
3046
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003047 def test_add_revoked_keyword(self):
3048 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003049 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003050 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003051 """
3052 crl = CRL()
3053 revoked = Revoked()
3054 crl.add_revoked(revoked=revoked)
3055 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3056
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003057 def test_export_wrong_args(self):
3058 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003059 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003060 four arguments, or with arguments other than the certificate,
3061 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003062 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003063 """
3064 crl = CRL()
3065 self.assertRaises(TypeError, crl.export)
3066 self.assertRaises(TypeError, crl.export, self.cert)
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003067 self.assertRaises(TypeError, crl.export, self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003068
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003069 self.assertRaises(TypeError, crl.export, None, self.pkey, FILETYPE_PEM, 10)
3070 self.assertRaises(TypeError, crl.export, self.cert, None, FILETYPE_PEM, 10)
3071 self.assertRaises(TypeError, crl.export, self.cert, self.pkey, None, 10)
3072 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3073
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003074 def test_export_unknown_filetype(self):
3075 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003076 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003077 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3078 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003079 """
3080 crl = CRL()
3081 self.assertRaises(ValueError, crl.export, self.cert, self.pkey, 100, 10)
3082
3083
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003084 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003085 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003086 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003087 in a :py:obj:`ValueError` being raised.
3088 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003089 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003090 self.assertRaises(
3091 ValueError,
3092 crl.export,
3093 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3094 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003095
Rick Dean536ba022009-07-24 23:57:27 -05003096 def test_get_revoked(self):
3097 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003098 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003099 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3100 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003101 """
3102 crl = CRL()
3103
3104 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003105 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003106 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003107 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003108 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003109 revoked.set_serial(b('100'))
3110 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003111 crl.add_revoked(revoked)
3112
3113 revs = crl.get_revoked()
3114 self.assertEqual(len(revs), 2)
3115 self.assertEqual(type(revs[0]), Revoked)
3116 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003117 self.assertEqual(revs[0].get_serial(), b('03AB'))
3118 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003119 self.assertEqual(revs[0].get_rev_date(), now)
3120 self.assertEqual(revs[1].get_rev_date(), now)
3121
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003122 def test_get_revoked_wrong_args(self):
3123 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003124 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3125 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003126 """
3127 crl = CRL()
3128 self.assertRaises(TypeError, crl.get_revoked, None)
3129 self.assertRaises(TypeError, crl.get_revoked, 1)
3130 self.assertRaises(TypeError, crl.get_revoked, "")
3131 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3132
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003133 def test_add_revoked_wrong_args(self):
3134 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003135 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3136 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003137 """
3138 crl = CRL()
3139 self.assertRaises(TypeError, crl.add_revoked)
3140 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3141 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3142
Rick Dean536ba022009-07-24 23:57:27 -05003143 def test_load_crl(self):
3144 """
3145 Load a known CRL and inspect its revocations. Both
3146 PEM and DER formats are loaded.
3147 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003148 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003149 revs = crl.get_revoked()
3150 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003151 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003152 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003153 self.assertEqual(revs[1].get_serial(), b('0100'))
3154 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003155
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003156 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003157 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003158 revs = crl.get_revoked()
3159 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003160 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003161 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003162 self.assertEqual(revs[1].get_serial(), b('0100'))
3163 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003164
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003165 def test_load_crl_wrong_args(self):
3166 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003167 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3168 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003169 """
3170 self.assertRaises(TypeError, load_crl)
3171 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3172 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3173
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003174 def test_load_crl_bad_filetype(self):
3175 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003176 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3177 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003178 """
3179 self.assertRaises(ValueError, load_crl, 100, crlData)
3180
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003181 def test_load_crl_bad_data(self):
3182 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003183 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3184 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003185 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003186 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003187
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003188
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003189class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003190 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003191 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003192 """
3193 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3194 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003195 intermediate_server_cert = load_certificate(
3196 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003197
3198 def test_valid(self):
3199 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003200 :py:obj:`verify_certificate` returns ``None`` when called with a
3201 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003202 """
3203 store = X509Store()
3204 store.add_cert(self.root_cert)
3205 store.add_cert(self.intermediate_cert)
3206 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003207 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003208
3209 def test_reuse(self):
3210 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003211 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003212 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003213 """
3214 store = X509Store()
3215 store.add_cert(self.root_cert)
3216 store.add_cert(self.intermediate_cert)
3217 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003218 self.assertEqual(store_ctx.verify_certificate(), None)
3219 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003220
3221 def test_trusted_self_signed(self):
3222 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003223 :py:obj:`verify_certificate` returns ``None`` when called with a
3224 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003225 """
3226 store = X509Store()
3227 store.add_cert(self.root_cert)
3228 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003229 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003230
3231 def test_untrusted_self_signed(self):
3232 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003233 :py:obj:`verify_certificate` raises error when a self-signed
3234 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003235 """
3236 store = X509Store()
3237 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003238 e = self.assertRaises(X509StoreContextError, store_ctx.verify_certificate)
Jean-Paul Calderone4c10a1e2015-01-18 16:31:27 -05003239 self.assertEqual(e.args[0][2], 'self signed certificate')
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003240 self.assertEqual(e.certificate.get_subject().CN, 'Testing Root CA')
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003241
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003242 def test_invalid_chain_no_root(self):
3243 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003244 :py:obj:`verify_certificate` raises error when a root certificate is
3245 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003246 """
3247 store = X509Store()
3248 store.add_cert(self.intermediate_cert)
3249 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003250 e = self.assertRaises(X509StoreContextError, store_ctx.verify_certificate)
Jean-Paul Calderone4c10a1e2015-01-18 16:31:27 -05003251 self.assertEqual(e.args[0][2], 'unable to get issuer certificate')
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003252 self.assertEqual(e.certificate.get_subject().CN, 'intermediate')
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003253
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003254 def test_invalid_chain_no_intermediate(self):
3255 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003256 :py:obj:`verify_certificate` raises error when an intermediate
3257 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003258 """
3259 store = X509Store()
3260 store.add_cert(self.root_cert)
3261 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003262 e = self.assertRaises(X509StoreContextError, store_ctx.verify_certificate)
Jean-Paul Calderone4c10a1e2015-01-18 16:31:27 -05003263 self.assertEqual(e.args[0][2], 'unable to get local issuer certificate')
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003264 self.assertEqual(e.certificate.get_subject().CN, 'intermediate-service')
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003265
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003266
Stephen Holsapple46a09252015-02-12 14:45:43 -08003267 def test_modification_pre_verify(self):
3268 """
3269 :py:obj:`verify_certificate` can use a store context modified after
3270 instantiation.
3271 """
3272 store_bad = X509Store()
3273 store_bad.add_cert(self.intermediate_cert)
3274 store_good = X509Store()
3275 store_good.add_cert(self.root_cert)
3276 store_good.add_cert(self.intermediate_cert)
3277 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
3278 e = self.assertRaises(X509StoreContextError, store_ctx.verify_certificate)
3279 self.assertEqual(e.args[0][2], 'unable to get issuer certificate')
3280 self.assertEqual(e.certificate.get_subject().CN, 'intermediate')
3281 store_ctx.set_store(store_good)
3282 self.assertEqual(store_ctx.verify_certificate(), None)
3283
3284
James Yonan7c2e5d32010-02-27 05:45:50 -07003285class SignVerifyTests(TestCase):
3286 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003287 Tests for :py:obj:`OpenSSL.crypto.sign` and
3288 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003289 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003290
James Yonan7c2e5d32010-02-27 05:45:50 -07003291 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003292 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003293 :py:obj:`sign` generates a cryptographic signature which
3294 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003295 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003296 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003297 "It was a bright cold day in April, and the clocks were striking "
3298 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3299 "effort to escape the vile wind, slipped quickly through the "
3300 "glass doors of Victory Mansions, though not quickly enough to "
3301 "prevent a swirl of gritty dust from entering along with him.")
3302
3303 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003304 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003305 # verify the content with this cert
3306 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3307 # certificate unrelated to priv_key, used to trigger an error
3308 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003309
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003310 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003311 sig = sign(priv_key, content, digest)
3312
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003313 # Verify the signature of content, will throw an exception if
3314 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003315 verify(good_cert, sig, content, digest)
3316
3317 # This should fail because the certificate doesn't match the
3318 # private key that was used to sign the content.
3319 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3320
3321 # This should fail because we've "tainted" the content after
3322 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003323 self.assertRaises(
3324 Error, verify,
3325 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003326
3327 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003328 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003329 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003330 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003331 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003332
Abraham Martinc5484ba2015-03-25 15:33:05 +00003333 def test_sign_verify_with_text(self):
3334 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003335 :py:obj:`sign` generates a cryptographic signature which
3336 :py:obj:`verify` can check. Deprecation warnings raised because using
3337 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003338 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003339 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003340 b"It was a bright cold day in April, and the clocks were striking "
3341 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3342 b"effort to escape the vile wind, slipped quickly through the "
3343 b"glass doors of Victory Mansions, though not quickly enough to "
3344 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003345 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003346
3347 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3348 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3349 for digest in ['md5', 'sha1']:
3350 with catch_warnings(record=True) as w:
3351 simplefilter("always")
3352 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003353
3354 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003355 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003356 WARNING_TYPE_EXPECTED
3357 ),
3358 str(w[-1].message)
3359 )
3360 self.assertIs(w[-1].category, DeprecationWarning)
3361
Abraham Martinc5484ba2015-03-25 15:33:05 +00003362 with catch_warnings(record=True) as w:
3363 simplefilter("always")
3364 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003365
3366 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003367 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003368 WARNING_TYPE_EXPECTED
3369 ),
3370 str(w[-1].message)
3371 )
3372 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003373
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003374 def test_sign_nulls(self):
3375 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003376 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003377 """
3378 content = b("Watch out! \0 Did you see it?")
3379 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3380 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3381 sig = sign(priv_key, content, "sha1")
3382 verify(good_cert, sig, content, "sha1")
3383
3384
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003385class EllipticCurveTests(TestCase):
3386 """
3387 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3388 :py:obj:`get_elliptic_curves`.
3389 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003390
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003391 def test_set(self):
3392 """
3393 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3394 """
3395 self.assertIsInstance(get_elliptic_curves(), set)
3396
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003397 def test_some_curves(self):
3398 """
3399 If :py:mod:`cryptography` has elliptic curve support then the set
3400 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3401 it.
3402
3403 There could be an OpenSSL that violates this assumption. If so, this
3404 test will fail and we'll find out.
3405 """
3406 curves = get_elliptic_curves()
3407 if lib.Cryptography_HAS_EC:
3408 self.assertTrue(curves)
3409 else:
3410 self.assertFalse(curves)
3411
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003412 def test_a_curve(self):
3413 """
3414 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3415 supported curve.
3416 """
3417 curves = get_elliptic_curves()
3418 if curves:
3419 curve = next(iter(curves))
3420 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3421 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003422 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003423
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003424 def test_not_a_curve(self):
3425 """
3426 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3427 with a name which does not identify a supported curve.
3428 """
3429 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003430 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003431
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003432 def test_repr(self):
3433 """
3434 The string representation of a curve object includes simply states the
3435 object is a curve and what its name is.
3436 """
3437 curves = get_elliptic_curves()
3438 if curves:
3439 curve = next(iter(curves))
3440 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3441
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003442 def test_to_EC_KEY(self):
3443 """
3444 The curve object can export a version of itself as an EC_KEY* via the
3445 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3446 """
3447 curves = get_elliptic_curves()
3448 if curves:
3449 curve = next(iter(curves))
3450 # It's not easy to assert anything about this object. However, see
3451 # leakcheck/crypto.py for a test that demonstrates it at least does
3452 # not leak memory.
3453 curve._to_EC_KEY()
3454
3455
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003456class EllipticCurveFactory(object):
3457 """
3458 A helper to get the names of two curves.
3459 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003460
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003461 def __init__(self):
3462 curves = iter(get_elliptic_curves())
3463 try:
3464 self.curve_name = next(curves).name
3465 self.another_curve_name = next(curves).name
3466 except StopIteration:
3467 self.curve_name = self.another_curve_name = None
3468
3469
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003470class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3471 """
3472 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3473 """
3474 curve_factory = EllipticCurveFactory()
3475
3476 if curve_factory.curve_name is None:
3477 skip = "There are no curves available there can be no curve objects."
3478
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003479 def anInstance(self):
3480 """
3481 Get the curve object for an arbitrary curve supported by the system.
3482 """
3483 return get_elliptic_curve(self.curve_factory.curve_name)
3484
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003485 def anotherInstance(self):
3486 """
3487 Get the curve object for an arbitrary curve supported by the system -
3488 but not the one returned by C{anInstance}.
3489 """
3490 return get_elliptic_curve(self.curve_factory.another_curve_name)
3491
3492
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003493class EllipticCurveHashTests(TestCase):
3494 """
3495 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3496 as an item in a :py:type:`dict` or :py:type:`set`).
3497 """
3498 curve_factory = EllipticCurveFactory()
3499
3500 if curve_factory.curve_name is None:
3501 skip = "There are no curves available there can be no curve objects."
3502
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003503 def test_contains(self):
3504 """
3505 The ``in`` operator reports that a :py:type:`set` containing a curve
3506 does contain that curve.
3507 """
3508 curve = get_elliptic_curve(self.curve_factory.curve_name)
3509 curves = set([curve])
3510 self.assertIn(curve, curves)
3511
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003512 def test_does_not_contain(self):
3513 """
3514 The ``in`` operator reports that a :py:type:`set` not containing a
3515 curve does not contain that curve.
3516 """
3517 curve = get_elliptic_curve(self.curve_factory.curve_name)
3518 curves = set([get_elliptic_curve(self.curve_factory.another_curve_name)])
3519 self.assertNotIn(curve, curves)
3520
3521
Rick Dean5b7b6372009-04-01 11:34:06 -05003522if __name__ == '__main__':
3523 main()