blob: e0feda2d0098f3d200f09af51ce914f88195e376 [file] [log] [blame]
Jean-Paul Calderone8671c852011-03-02 19:26:20 -05001# Copyright (c) Jean-Paul Calderone
2# See LICENSE file for details.
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04003
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05004"""
Jonathan Ballet648875f2011-07-16 14:14:58 +09005Unit tests for :py:mod:`OpenSSL.crypto`.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05006"""
7
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04008from unittest import main
Jean-Paul Calderone60432792015-04-13 12:26:07 -04009from warnings import catch_warnings, simplefilter
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -040010
Alex Gaynor4b9c96a2014-08-14 09:51:48 -070011import base64
12import os
13import re
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -040014from subprocess import PIPE, Popen
Rick Dean47262da2009-07-08 16:17:17 -050015from datetime import datetime, timedelta
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050016
Alex Gaynor791212d2015-09-05 15:46:08 -040017import pytest
18
Alex Gaynorb8e38992015-09-04 08:14:04 -040019from six import u, b, binary_type
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050020
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050021from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050022from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
Alex Gaynor31287502015-09-05 16:11:27 -040023from OpenSSL.crypto import (
24 X509Store, X509StoreType, X509StoreContext, X509StoreContextError
25)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070026from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -050027from OpenSSL.crypto import X509Extension, X509ExtensionType
Rick Dean5b7b6372009-04-01 11:34:06 -050028from OpenSSL.crypto import load_certificate, load_privatekey
Cory Benfield6492f7c2015-10-27 16:57:58 +090029from OpenSSL.crypto import load_publickey, dump_publickey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040030from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040031from OpenSSL.crypto import dump_certificate, load_certificate_request
32from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040033from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Jean-Paul Calderone9178ee62010-01-25 17:55:30 -050034from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000035from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040036from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040037from OpenSSL.crypto import (
38 sign, verify, get_elliptic_curve, get_elliptic_curves)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020039from OpenSSL._util import native, lib
40
41from .util import (
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040042 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
43)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040044
Alex Gaynoraceb3e22015-09-05 12:00:22 -040045
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040046def normalize_certificate_pem(pem):
47 return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
48
49
50def normalize_privatekey_pem(pem):
51 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
52
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040053
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050054GOOD_CIPHER = "blowfish"
55BAD_CIPHER = "zippers"
56
Anthony Alba2ce737f2015-12-04 11:04:56 +080057#GOOD_DIGEST = "MD5"
58# MD5 verification disabled in some distros OpenSSL
59GOOD_DIGEST = "SHA1"
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050060BAD_DIGEST = "monkeys"
61
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040062root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050063MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
64BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
65ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
66NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
67MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
68ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
69urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
702xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
711dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
72FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
73VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
74BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
75b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
76AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
77hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
78w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
79-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040080""")
Rick Dean94e46fd2009-07-18 14:51:24 -050081
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040082root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050083MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
84jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
853claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
86AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
87yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
886JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
89BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
90u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
91PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
92I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
93ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
946AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
95cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
96-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040097""")
Rick Dean94e46fd2009-07-18 14:51:24 -050098
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070099intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
100MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
101WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
102DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
103ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
104dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
105MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
106AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
107FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
10821H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
109AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
110QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1119n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1129mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
113-----END CERTIFICATE-----
114""")
115
116intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
117MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
118ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
119qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
120AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
121rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
122147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
123+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
124wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
125sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
12652vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
127DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
128/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
129NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
130-----END RSA PRIVATE KEY-----
131""")
132
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400133server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500134MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
135BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
136VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
137NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
138gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
139lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
140b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
141lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
142gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
143dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1442mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
145uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
146-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400147""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500148
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400149server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500150MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
151U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
152SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
153AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
154j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
155j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
156Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
157msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
158FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1594e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1601sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
161NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
162r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
163-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400164"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500165
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700166intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
167MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
168ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
169CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
170biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
171BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
172CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
173biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
174iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
175+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
176biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
177UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1783bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
179x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
180-----END CERTIFICATE-----
181""")
182
183intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
184MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
185SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1868Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
187AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1885ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
189d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
190z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
191dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
192EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
193X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
1949UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
195ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
196nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
197-----END RSA PRIVATE KEY-----
198""")
199
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400200client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500201MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
202BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
203VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
204ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
205MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
206rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
207iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
208oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2090fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
210Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2119Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
212PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
213-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400214""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500215
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400216client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500217MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
218btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
219eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
220AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
221zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
222h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
223V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
224TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
225dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
226D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
227si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
228JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
229f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
230-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400231"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400232
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400233cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400234MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
235BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
236ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
237NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
238MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
239ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
240urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2412xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2421dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
243FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
244VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
245BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
246b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
247AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
248hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
249w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
250-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400251""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400252
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400253cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
254-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400255MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
256jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2573claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
258AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
259yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2606JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
261BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
262u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
263PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
264I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
265ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2666AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
267cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
268-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400269"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400270
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400271cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
272MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
273EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
274ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
275BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
276E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
277xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
278gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
279Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
280oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
281-----END CERTIFICATE REQUEST-----
282""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500283
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400284encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400285Proc-Type: 4,ENCRYPTED
286DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400287
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400288SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
289a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2908+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
291mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
292+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
293fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
294tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
295rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
296gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
297o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
2987SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
299MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
30011n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
301-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400302""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400303
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400304encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400305
Cory Benfield6492f7c2015-10-27 16:57:58 +0900306
307cleartextPublicKeyPEM = b("""-----BEGIN PUBLIC KEY-----
308MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
309gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
31090qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
311ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
312XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
3138Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
314ywIDAQAB
315-----END PUBLIC KEY-----
316""")
317
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400318# Some PKCS#7 stuff. Generated with the openssl command line:
319#
320# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
321#
322# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400323pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400324-----BEGIN PKCS7-----
325MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
326BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
327A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
328MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
329cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
330A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
331HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
332SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
333zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
334LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
335A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
33665w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
337Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
338Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
339bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
340VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
341/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
342Ho4EzbYCOaEAMQA=
343-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400344""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400345
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700346pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700347MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
348BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
349A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
350MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
351cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
352A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
353HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
354SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
355zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
356LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
357A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
35865w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
359Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
360Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
361bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
362VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
363/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
364Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700365""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700366
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400367crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500368-----BEGIN X509 CRL-----
369MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
370SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
371D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
372MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
373MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3744dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3750yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
376vrzEeLDRiiPl92dyyWmu
377-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400378""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400379
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400380
381# A broken RSA private key which can be used to test the error path through
382# PKey.check.
383inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
384MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
3855kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
386OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
387zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
388nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
389HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
390oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
391-----END RSA PRIVATE KEY-----
392""")
393
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400394# certificate with NULL bytes in subjectAltName and common name
395
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400396nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400397MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
398DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
399eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
400RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
401ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
402NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
403DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
404ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
405ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
406hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
407BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
408pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
409vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
410KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
411oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
41208LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
413HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
414BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
415Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
416bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
417AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
418i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
419HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
420kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
421VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
422RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
423-----END CERTIFICATE-----""")
424
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400425
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400426class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400427 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900428 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400429 """
430
431 def setUp(self):
432 """
433 Create a new private key and start a certificate request (for a test
434 method to finish in one way or another).
435 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800436 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400437 # Basic setup stuff to generate a certificate
438 self.pkey = PKey()
439 self.pkey.generate_key(TYPE_RSA, 384)
440 self.req = X509Req()
441 self.req.set_pubkey(self.pkey)
442 # Authority good you have.
443 self.req.get_subject().commonName = "Yoda root CA"
444 self.x509 = X509()
445 self.subject = self.x509.get_subject()
446 self.subject.commonName = self.req.get_subject().commonName
447 self.x509.set_issuer(self.subject)
448 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400449 now = datetime.now()
450 expire = datetime.now() + timedelta(days=100)
451 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
452 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400453
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800454 def tearDown(self):
455 """
456 Forget all of the pyOpenSSL objects so they can be garbage collected,
457 their memory released, and not interfere with the leak detection code.
458 """
459 self.pkey = self.req = self.x509 = self.subject = None
460 super(X509ExtTests, self).tearDown()
461
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400462 def test_str(self):
463 """
Alex Gaynor31287502015-09-05 16:11:27 -0400464 The string representation of :py:class:`X509Extension` instances as
465 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400466 """
467 # This isn't necessarily the best string representation. Perhaps it
468 # will be changed/improved in the future.
469 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400470 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400471 'CA:FALSE')
472
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400473 def test_type(self):
474 """
Alex Gaynor31287502015-09-05 16:11:27 -0400475 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
476 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400477 """
478 self.assertIdentical(X509Extension, X509ExtensionType)
479 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400480 X509Extension,
481 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400482
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500483 def test_construction(self):
484 """
Alex Gaynor31287502015-09-05 16:11:27 -0400485 :py:class:`X509Extension` accepts an extension type name, a critical
486 flag, and an extension value and returns an
487 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500488 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400489 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500490 self.assertTrue(
491 isinstance(basic, X509ExtensionType),
492 "%r is of type %r, should be %r" % (
493 basic, type(basic), X509ExtensionType))
494
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400495 comment = X509Extension(
496 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500497 self.assertTrue(
498 isinstance(comment, X509ExtensionType),
499 "%r is of type %r, should be %r" % (
500 comment, type(comment), X509ExtensionType))
501
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500502 def test_invalid_extension(self):
503 """
Alex Gaynor31287502015-09-05 16:11:27 -0400504 :py:class:`X509Extension` raises something if it is passed a bad
505 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500506 """
507 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400508 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500509 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400510 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500511
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500512 # Exercise a weird one (an extension which uses the r2i method). This
513 # exercises the codepath that requires a non-NULL ctx to be passed to
514 # X509V3_EXT_nconf. It can't work now because we provide no
515 # configuration database. It might be made to work in the future.
516 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400517 Error, X509Extension, b('proxyCertInfo'), True,
518 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500519
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500520 def test_get_critical(self):
521 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900522 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500523 extension's critical flag.
524 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400525 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500526 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400527 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500528 self.assertFalse(ext.get_critical())
529
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500530 def test_get_short_name(self):
531 """
Alex Gaynor31287502015-09-05 16:11:27 -0400532 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
533 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500534 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400535 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
536 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
537 ext = X509Extension(b('nsComment'), True, b('foo bar'))
538 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500539
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400540 def test_get_data(self):
541 """
Alex Gaynor31287502015-09-05 16:11:27 -0400542 :py:meth:`X509Extension.get_data` returns a string giving the data of
543 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400544 """
545 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
546 # Expect to get back the DER encoded form of CA:true.
547 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
548
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400549 def test_get_data_wrong_args(self):
550 """
Alex Gaynor31287502015-09-05 16:11:27 -0400551 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
552 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400553 """
554 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
555 self.assertRaises(TypeError, ext.get_data, None)
556 self.assertRaises(TypeError, ext.get_data, "foo")
557 self.assertRaises(TypeError, ext.get_data, 7)
558
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400559 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500560 """
Alex Gaynor31287502015-09-05 16:11:27 -0400561 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
562 provided for an extension which does not use it and is ignored in this
563 case.
Rick Dean47262da2009-07-08 16:17:17 -0500564 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400565 ext1 = X509Extension(
566 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400567 self.x509.add_extensions([ext1])
568 self.x509.sign(self.pkey, 'sha1')
569 # This is a little lame. Can we think of a better way?
570 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400571 self.assertTrue(b('X509v3 Basic Constraints:') in text)
572 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400573
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400574 def test_subject(self):
575 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900576 If an extension requires a subject, the :py:data:`subject` parameter to
577 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400578 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400579 ext3 = X509Extension(
580 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400581 self.x509.add_extensions([ext3])
582 self.x509.sign(self.pkey, 'sha1')
583 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400584 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400585
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400586 def test_missing_subject(self):
587 """
Alex Gaynor31287502015-09-05 16:11:27 -0400588 If an extension requires a subject and the :py:data:`subject` parameter
589 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400590 """
591 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400592 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400593
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400594 def test_invalid_subject(self):
595 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900596 If the :py:data:`subject` parameter is given a value which is not an
597 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400598 """
599 for badObj in [True, object(), "hello", [], self]:
600 self.assertRaises(
601 TypeError,
602 X509Extension,
603 'basicConstraints', False, 'CA:TRUE', subject=badObj)
604
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400605 def test_unused_issuer(self):
606 """
Alex Gaynor31287502015-09-05 16:11:27 -0400607 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
608 provided for an extension which does not use it and is ignored in this
609 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400610 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400611 ext1 = X509Extension(
612 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400613 self.x509.add_extensions([ext1])
614 self.x509.sign(self.pkey, 'sha1')
615 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400616 self.assertTrue(b('X509v3 Basic Constraints:') in text)
617 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400618
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400619 def test_issuer(self):
620 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800621 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900622 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400623 """
624 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400625 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400626 issuer=self.x509)
627 self.x509.add_extensions([ext2])
628 self.x509.sign(self.pkey, 'sha1')
629 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400630 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
631 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400632
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400633 def test_missing_issuer(self):
634 """
Alex Gaynor31287502015-09-05 16:11:27 -0400635 If an extension requires an issue and the :py:data:`issuer` parameter
636 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400637 """
638 self.assertRaises(
639 Error,
640 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400641 b('authorityKeyIdentifier'), False,
642 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400643
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400644 def test_invalid_issuer(self):
645 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900646 If the :py:data:`issuer` parameter is given a value which is not an
647 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400648 """
649 for badObj in [True, object(), "hello", [], self]:
650 self.assertRaises(
651 TypeError,
652 X509Extension,
653 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
654 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500655
656
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400657class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500658 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900659 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500660 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400661
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400662 def test_type(self):
663 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900664 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
665 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400666 """
667 self.assertIdentical(PKey, PKeyType)
668 self.assertConsistentType(PKey, 'PKey')
669
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500670 def test_construction(self):
671 """
Alex Gaynor31287502015-09-05 16:11:27 -0400672 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
673 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500674 """
675 self.assertRaises(TypeError, PKey, None)
676 key = PKey()
677 self.assertTrue(
678 isinstance(key, PKeyType),
679 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
680
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500681 def test_pregeneration(self):
682 """
Alex Gaynor31287502015-09-05 16:11:27 -0400683 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
684 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
685 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500686 """
687 key = PKey()
688 self.assertEqual(key.type(), 0)
689 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400690 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500691
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500692 def test_failedGeneration(self):
693 """
Alex Gaynor31287502015-09-05 16:11:27 -0400694 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
695 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
696 the second giving the number of bits to generate. If an invalid type
697 is specified or generation fails, :py:exc:`Error` is raised. If an
698 invalid number of bits is specified, :py:exc:`ValueError` or
699 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500700 """
701 key = PKey()
702 self.assertRaises(TypeError, key.generate_key)
703 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
704 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
705 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500706
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500707 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
708 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500709
710 # XXX RSA generation for small values of bits is fairly buggy in a wide
711 # range of OpenSSL versions. I need to figure out what the safe lower
712 # bound for a reasonable number of OpenSSL versions is and explicitly
713 # check for that in the wrapper. The failure behavior is typically an
714 # infinite loop inside OpenSSL.
715
716 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500717
718 # XXX DSA generation seems happy with any number of bits. The DSS
719 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
720 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500721 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500722 # So, it doesn't seem possible to make generate_key fail for
723 # TYPE_DSA with a bits argument which is at least an int.
724
725 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
726
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500727 def test_rsaGeneration(self):
728 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900729 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
730 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500731 """
732 bits = 128
733 key = PKey()
734 key.generate_key(TYPE_RSA, bits)
735 self.assertEqual(key.type(), TYPE_RSA)
736 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400737 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500738
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500739 def test_dsaGeneration(self):
740 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900741 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
742 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500743 """
744 # 512 is a magic number. The DSS (Digital Signature Standard)
745 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
746 # will silently promote any value below 512 to 512.
747 bits = 512
748 key = PKey()
749 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800750 # self.assertEqual(key.type(), TYPE_DSA)
751 # self.assertEqual(key.bits(), bits)
752 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500753
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500754 def test_regeneration(self):
755 """
Alex Gaynor31287502015-09-05 16:11:27 -0400756 :py:meth:`PKeyType.generate_key` can be called multiple times on the
757 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500758 """
759 key = PKey()
760 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400761 key.generate_key(type, bits)
762 self.assertEqual(key.type(), type)
763 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500764
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400765 def test_inconsistentKey(self):
766 """
Alex Gaynor31287502015-09-05 16:11:27 -0400767 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
768 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400769 """
770 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400771 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400772
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400773 def test_check_wrong_args(self):
774 """
Alex Gaynor31287502015-09-05 16:11:27 -0400775 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
776 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400777 """
778 self.assertRaises(TypeError, PKey().check, None)
779 self.assertRaises(TypeError, PKey().check, object())
780 self.assertRaises(TypeError, PKey().check, 1)
781
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400782 def test_check_public_key(self):
783 """
784 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
785 part of the key is available.
786 """
787 # A trick to get a public-only key
788 key = PKey()
789 key.generate_key(TYPE_RSA, 512)
790 cert = X509()
791 cert.set_pubkey(key)
792 pub = cert.get_pubkey()
793 self.assertRaises(TypeError, pub.check)
794
795
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400796class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500797 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900798 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500799 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400800
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500801 def _x509name(self, **attrs):
802 # XXX There's no other way to get a new X509Name yet.
803 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400804 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400805
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500806 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400807 def key(attr):
808 return attr[1]
809 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500810 for k, v in attrs:
811 setattr(name, k, v)
812 return name
813
Rick Deane15b1472009-07-09 15:53:42 -0500814 def test_type(self):
815 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900816 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500817 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400818 self.assertIdentical(X509Name, X509NameType)
819 self.assertEqual(X509NameType.__name__, 'X509Name')
820 self.assertTrue(isinstance(X509NameType, type))
821
Rick Deane15b1472009-07-09 15:53:42 -0500822 name = self._x509name()
823 self.assertTrue(
824 isinstance(name, X509NameType),
825 "%r is of type %r, should be %r" % (
826 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500827
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400828 def test_onlyStringAttributes(self):
829 """
Alex Gaynor31287502015-09-05 16:11:27 -0400830 Attempting to set a non-:py:data:`str` attribute name on an
831 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
832 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400833 """
834 name = self._x509name()
835 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400836 # rejected. Sorry, you're wrong. unicode is automatically converted
837 # to str outside of the control of X509Name, so there's no way to
838 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800839
Alex Gaynor31287502015-09-05 16:11:27 -0400840 # Also, this used to test str subclasses, but that test is less
841 # relevant now that the implementation is in Python instead of C. Also
842 # PyPy automatically converts str subclasses to str when they are
843 # passed to setattr, so we can't test it on PyPy. Apparently CPython
844 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400845 self.assertRaises(TypeError, setattr, name, None, "hello")
846 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400847
848 def test_setInvalidAttribute(self):
849 """
Alex Gaynor31287502015-09-05 16:11:27 -0400850 Attempting to set any attribute name on an :py:class:`X509NameType`
851 instance for which no corresponding NID is defined causes
852 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400853 """
854 name = self._x509name()
855 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
856
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500857 def test_attributes(self):
858 """
Alex Gaynor31287502015-09-05 16:11:27 -0400859 :py:class:`X509NameType` instances have attributes for each standard
860 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500861 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500862 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500863 name.commonName = "foo"
864 self.assertEqual(name.commonName, "foo")
865 self.assertEqual(name.CN, "foo")
866 name.CN = "baz"
867 self.assertEqual(name.commonName, "baz")
868 self.assertEqual(name.CN, "baz")
869 name.commonName = "bar"
870 self.assertEqual(name.commonName, "bar")
871 self.assertEqual(name.CN, "bar")
872 name.CN = "quux"
873 self.assertEqual(name.commonName, "quux")
874 self.assertEqual(name.CN, "quux")
875
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500876 def test_copy(self):
877 """
Alex Gaynor31287502015-09-05 16:11:27 -0400878 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
879 with all the same attributes as an existing :py:class:`X509NameType`
880 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500881 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500882 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500883
884 copy = X509Name(name)
885 self.assertEqual(copy.commonName, "foo")
886 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500887
888 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500889 copy.commonName = "baz"
890 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500891
892 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500893 name.emailAddress = "quux@example.com"
894 self.assertEqual(copy.emailAddress, "bar@example.com")
895
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500896 def test_repr(self):
897 """
Alex Gaynor31287502015-09-05 16:11:27 -0400898 :py:func:`repr` passed an :py:class:`X509NameType` instance should
899 return a string containing a description of the type and the NIDs which
900 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500901 """
902 name = self._x509name(commonName="foo", emailAddress="bar")
903 self.assertEqual(
904 repr(name),
905 "<X509Name object '/emailAddress=bar/CN=foo'>")
906
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500907 def test_comparison(self):
908 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900909 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500910 """
911 def _equality(a, b, assertTrue, assertFalse):
912 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
913 assertFalse(a != b)
914 assertTrue(b == a)
915 assertFalse(b != a)
916
917 def assertEqual(a, b):
918 _equality(a, b, self.assertTrue, self.assertFalse)
919
920 # Instances compare equal to themselves.
921 name = self._x509name()
922 assertEqual(name, name)
923
924 # Empty instances should compare equal to each other.
925 assertEqual(self._x509name(), self._x509name())
926
927 # Instances with equal NIDs should compare equal to each other.
928 assertEqual(self._x509name(commonName="foo"),
929 self._x509name(commonName="foo"))
930
931 # Instance with equal NIDs set using different aliases should compare
932 # equal to each other.
933 assertEqual(self._x509name(commonName="foo"),
934 self._x509name(CN="foo"))
935
936 # Instances with more than one NID with the same values should compare
937 # equal to each other.
938 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
939 self._x509name(commonName="foo", OU="bar"))
940
941 def assertNotEqual(a, b):
942 _equality(a, b, self.assertFalse, self.assertTrue)
943
944 # Instances with different values for the same NID should not compare
945 # equal to each other.
946 assertNotEqual(self._x509name(CN="foo"),
947 self._x509name(CN="bar"))
948
949 # Instances with different NIDs should not compare equal to each other.
950 assertNotEqual(self._x509name(CN="foo"),
951 self._x509name(OU="foo"))
952
953 def _inequality(a, b, assertTrue, assertFalse):
954 assertTrue(a < b)
955 assertTrue(a <= b)
956 assertTrue(b > a)
957 assertTrue(b >= a)
958 assertFalse(a > b)
959 assertFalse(a >= b)
960 assertFalse(b < a)
961 assertFalse(b <= a)
962
963 def assertLessThan(a, b):
964 _inequality(a, b, self.assertTrue, self.assertFalse)
965
966 # An X509Name with a NID with a value which sorts less than the value
967 # of the same NID on another X509Name compares less than the other
968 # X509Name.
969 assertLessThan(self._x509name(CN="abc"),
970 self._x509name(CN="def"))
971
972 def assertGreaterThan(a, b):
973 _inequality(a, b, self.assertFalse, self.assertTrue)
974
975 # An X509Name with a NID with a value which sorts greater than the
976 # value of the same NID on another X509Name compares greater than the
977 # other X509Name.
978 assertGreaterThan(self._x509name(CN="def"),
979 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500980
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400981 def test_hash(self):
982 """
Alex Gaynor31287502015-09-05 16:11:27 -0400983 :py:meth:`X509Name.hash` returns an integer hash based on the value of
984 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400985 """
986 a = self._x509name(CN="foo")
987 b = self._x509name(CN="foo")
988 self.assertEqual(a.hash(), b.hash())
989 a.CN = "bar"
990 self.assertNotEqual(a.hash(), b.hash())
991
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400992 def test_der(self):
993 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900994 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400995 """
996 a = self._x509name(CN="foo", C="US")
997 self.assertEqual(
998 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400999 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001000 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001001
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001002 def test_get_components(self):
1003 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001004 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1005 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001006 giving the NIDs and associated values which make up the name.
1007 """
1008 a = self._x509name()
1009 self.assertEqual(a.get_components(), [])
1010 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001011 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001012 a.organizationalUnitName = "bar"
1013 self.assertEqual(
1014 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001015 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001016
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001017 def test_load_nul_byte_attribute(self):
1018 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001019 An :py:class:`OpenSSL.crypto.X509Name` from an
1020 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001021 NUL byte in the value of one of its attributes.
1022 """
1023 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1024 subject = cert.get_subject()
1025 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001026 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001027
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001028 def test_setAttributeFailure(self):
1029 """
1030 If the value of an attribute cannot be set for some reason then
1031 :py:class:`OpenSSL.crypto.Error` is raised.
1032 """
1033 name = self._x509name()
1034 # This value is too long
1035 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1036
1037
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001038class _PKeyInteractionTestsMixin:
1039 """
1040 Tests which involve another thing and a PKey.
1041 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001042
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001043 def signable(self):
1044 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001045 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1046 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001047 """
1048 raise NotImplementedError()
1049
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001050 def test_signWithUngenerated(self):
1051 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001052 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1053 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001054 """
1055 request = self.signable()
1056 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001057 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001058
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001059 def test_signWithPublicKey(self):
1060 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001061 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1062 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001063 """
1064 request = self.signable()
1065 key = PKey()
1066 key.generate_key(TYPE_RSA, 512)
1067 request.set_pubkey(key)
1068 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001069 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001070
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001071 def test_signWithUnknownDigest(self):
1072 """
Alex Gaynor31287502015-09-05 16:11:27 -04001073 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1074 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001075 """
1076 request = self.signable()
1077 key = PKey()
1078 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001079 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001080
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001081 def test_sign(self):
1082 """
Alex Gaynor31287502015-09-05 16:11:27 -04001083 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1084 valid digest function. :py:meth:`X509Req.verify` can be used to check
1085 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001086 """
1087 request = self.signable()
1088 key = PKey()
1089 key.generate_key(TYPE_RSA, 512)
1090 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001091 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001092 # If the type has a verify method, cover that too.
1093 if getattr(request, 'verify', None) is not None:
1094 pub = request.get_pubkey()
1095 self.assertTrue(request.verify(pub))
1096 # Make another key that won't verify.
1097 key = PKey()
1098 key.generate_key(TYPE_RSA, 512)
1099 self.assertRaises(Error, request.verify, key)
1100
1101
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001102class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001103 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001104 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001105 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001106
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001107 def signable(self):
1108 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001109 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001110 """
1111 return X509Req()
1112
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001113 def test_type(self):
1114 """
Alex Gaynor31287502015-09-05 16:11:27 -04001115 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1116 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001117 """
1118 self.assertIdentical(X509Req, X509ReqType)
1119 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001120
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001121 def test_construction(self):
1122 """
Alex Gaynor31287502015-09-05 16:11:27 -04001123 :py:obj:`X509Req` takes no arguments and returns an
1124 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001125 """
1126 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001127 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001128
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001129 def test_version(self):
1130 """
Alex Gaynor31287502015-09-05 16:11:27 -04001131 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1132 certificate request. :py:obj:`X509ReqType.get_version` returns the
1133 X.509 version of the certificate request. The initial value of the
1134 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001135 """
1136 request = X509Req()
1137 self.assertEqual(request.get_version(), 0)
1138 request.set_version(1)
1139 self.assertEqual(request.get_version(), 1)
1140 request.set_version(3)
1141 self.assertEqual(request.get_version(), 3)
1142
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001143 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001144 """
Alex Gaynor31287502015-09-05 16:11:27 -04001145 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1146 with the wrong number of arguments or with a non-:py:obj:`int`
1147 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1148 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001149 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001150 request = X509Req()
1151 self.assertRaises(TypeError, request.set_version)
1152 self.assertRaises(TypeError, request.set_version, "foo")
1153 self.assertRaises(TypeError, request.set_version, 1, 2)
1154 self.assertRaises(TypeError, request.get_version, None)
1155
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001156 def test_get_subject(self):
1157 """
Alex Gaynor31287502015-09-05 16:11:27 -04001158 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1159 subject of the request and which is valid even after the request object
1160 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001161 """
1162 request = X509Req()
1163 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001164 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001165 subject.commonName = "foo"
1166 self.assertEqual(request.get_subject().commonName, "foo")
1167 del request
1168 subject.commonName = "bar"
1169 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001170
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001171 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001172 """
Alex Gaynor31287502015-09-05 16:11:27 -04001173 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1174 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001175 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001176 request = X509Req()
1177 self.assertRaises(TypeError, request.get_subject, None)
1178
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001179 def test_add_extensions(self):
1180 """
Alex Gaynor31287502015-09-05 16:11:27 -04001181 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1182 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001183 """
1184 request = X509Req()
1185 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001186 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001187 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001188 self.assertEqual(len(exts), 1)
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\x00'))
1192
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001193 def test_get_extensions(self):
1194 """
1195 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1196 extensions added to this X509 request.
1197 """
1198 request = X509Req()
1199 exts = request.get_extensions()
1200 self.assertEqual(exts, [])
1201 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001202 X509Extension(b('basicConstraints'), True, b('CA:true')),
1203 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001204 exts = request.get_extensions()
1205 self.assertEqual(len(exts), 2)
1206 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1207 self.assertEqual(exts[0].get_critical(), 1)
1208 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1209 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1210 self.assertEqual(exts[1].get_critical(), 0)
1211 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001212
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001213 def test_add_extensions_wrong_args(self):
1214 """
Alex Gaynor31287502015-09-05 16:11:27 -04001215 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1216 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1217 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1218 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001219 """
1220 request = X509Req()
1221 self.assertRaises(TypeError, request.add_extensions)
1222 self.assertRaises(TypeError, request.add_extensions, object())
1223 self.assertRaises(ValueError, request.add_extensions, [object()])
1224 self.assertRaises(TypeError, request.add_extensions, [], None)
1225
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001226 def test_verify_wrong_args(self):
1227 """
1228 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1229 arguments or more than one argument or if passed anything other than a
1230 :py:obj:`PKey` instance as its single argument.
1231 """
1232 request = X509Req()
1233 self.assertRaises(TypeError, request.verify)
1234 self.assertRaises(TypeError, request.verify, object())
1235 self.assertRaises(TypeError, request.verify, PKey(), object())
1236
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001237 def test_verify_uninitialized_key(self):
1238 """
Alex Gaynor31287502015-09-05 16:11:27 -04001239 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1240 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001241 """
1242 request = X509Req()
1243 pkey = PKey()
1244 self.assertRaises(Error, request.verify, pkey)
1245
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001246 def test_verify_wrong_key(self):
1247 """
Alex Gaynor31287502015-09-05 16:11:27 -04001248 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1249 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1250 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001251 """
1252 request = X509Req()
1253 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001254 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001255 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1256 self.assertRaises(Error, request.verify, another_pkey)
1257
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001258 def test_verify_success(self):
1259 """
1260 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001261 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1262 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001263 """
1264 request = X509Req()
1265 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001266 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001267 self.assertEqual(True, request.verify(pkey))
1268
1269
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001270class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001271 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001272 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001273 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001274 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001275
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001276 extpem = """
1277-----BEGIN CERTIFICATE-----
1278MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1279BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1280eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1281MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1282aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1283hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1284Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1285zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1286hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1287TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
128803HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1289MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1290b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1291MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1292uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1293WpOdIpB8KksUTCzV591Nr1wd
1294-----END CERTIFICATE-----
1295 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001296
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001297 def signable(self):
1298 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001299 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001300 """
1301 return X509()
1302
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001303 def test_type(self):
1304 """
Alex Gaynor31287502015-09-05 16:11:27 -04001305 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1306 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001307 """
1308 self.assertIdentical(X509, X509Type)
1309 self.assertConsistentType(X509, 'X509')
1310
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001311 def test_construction(self):
1312 """
Alex Gaynor31287502015-09-05 16:11:27 -04001313 :py:obj:`X509` takes no arguments and returns an instance of
1314 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001315 """
1316 certificate = X509()
1317 self.assertTrue(
1318 isinstance(certificate, X509Type),
1319 "%r is of type %r, should be %r" % (certificate,
1320 type(certificate),
1321 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001322 self.assertEqual(type(X509Type).__name__, 'type')
1323 self.assertEqual(type(certificate).__name__, 'X509')
1324 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001325 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001326
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001327 def test_get_version_wrong_args(self):
1328 """
Alex Gaynor31287502015-09-05 16:11:27 -04001329 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1330 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001331 """
1332 cert = X509()
1333 self.assertRaises(TypeError, cert.get_version, None)
1334
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001335 def test_set_version_wrong_args(self):
1336 """
Alex Gaynor31287502015-09-05 16:11:27 -04001337 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1338 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001339 """
1340 cert = X509()
1341 self.assertRaises(TypeError, cert.set_version)
1342 self.assertRaises(TypeError, cert.set_version, None)
1343 self.assertRaises(TypeError, cert.set_version, 1, None)
1344
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001345 def test_version(self):
1346 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001347 :py:obj:`X509.set_version` sets the certificate version number.
1348 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001349 """
1350 cert = X509()
1351 cert.set_version(1234)
1352 self.assertEquals(cert.get_version(), 1234)
1353
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001354 def test_get_serial_number_wrong_args(self):
1355 """
Alex Gaynor31287502015-09-05 16:11:27 -04001356 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1357 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001358 """
1359 cert = X509()
1360 self.assertRaises(TypeError, cert.get_serial_number, None)
1361
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001362 def test_serial_number(self):
1363 """
Alex Gaynor31287502015-09-05 16:11:27 -04001364 The serial number of an :py:obj:`X509Type` can be retrieved and
1365 modified with :py:obj:`X509Type.get_serial_number` and
1366 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001367 """
1368 certificate = X509()
1369 self.assertRaises(TypeError, certificate.set_serial_number)
1370 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1371 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1372 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1373 self.assertEqual(certificate.get_serial_number(), 0)
1374 certificate.set_serial_number(1)
1375 self.assertEqual(certificate.get_serial_number(), 1)
1376 certificate.set_serial_number(2 ** 32 + 1)
1377 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1378 certificate.set_serial_number(2 ** 64 + 1)
1379 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001380 certificate.set_serial_number(2 ** 128 + 1)
1381 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1382
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001383 def _setBoundTest(self, which):
1384 """
Alex Gaynor31287502015-09-05 16:11:27 -04001385 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1386 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1387 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001388 """
1389 certificate = X509()
1390 set = getattr(certificate, 'set_not' + which)
1391 get = getattr(certificate, 'get_not' + which)
1392
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001393 # Starts with no value.
1394 self.assertEqual(get(), None)
1395
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001396 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001397 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001398 set(when)
1399 self.assertEqual(get(), when)
1400
1401 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001402 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001403 set(when)
1404 self.assertEqual(get(), when)
1405
1406 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001407 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001408 set(when)
1409 self.assertEqual(get(), when)
1410
1411 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001412 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001413
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001414 # The wrong number of arguments results in a TypeError.
1415 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001416 with pytest.raises(TypeError):
1417 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001418 self.assertRaises(TypeError, get, b("foo bar"))
1419
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001420 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001421
1422 def test_set_notBefore(self):
1423 """
Alex Gaynor31287502015-09-05 16:11:27 -04001424 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1425 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1426 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001427 """
1428 self._setBoundTest("Before")
1429
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001430 def test_set_notAfter(self):
1431 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001432 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001433 GENERALIZEDTIME and sets the end of the certificate's validity period
1434 to it.
1435 """
1436 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001437
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001438 def test_get_notBefore(self):
1439 """
Alex Gaynor31287502015-09-05 16:11:27 -04001440 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1441 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001442 internally.
1443 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001444 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001445 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001446
Rick Dean38a05c82009-07-18 01:41:30 -05001447 def test_get_notAfter(self):
1448 """
Alex Gaynor31287502015-09-05 16:11:27 -04001449 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1450 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001451 internally.
1452 """
1453 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001454 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001455
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001456 def test_gmtime_adj_notBefore_wrong_args(self):
1457 """
Alex Gaynor31287502015-09-05 16:11:27 -04001458 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1459 called with the wrong number of arguments or a non-:py:obj:`int`
1460 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001461 """
1462 cert = X509()
1463 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1464 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1465 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1466
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001467 def test_gmtime_adj_notBefore(self):
1468 """
Alex Gaynor31287502015-09-05 16:11:27 -04001469 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1470 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001471 """
1472 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001473 not_before_min = (
1474 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1475 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001476 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001477 not_before = datetime.strptime(
1478 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1479 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001480 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1481 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001482
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001483 def test_gmtime_adj_notAfter_wrong_args(self):
1484 """
Alex Gaynor31287502015-09-05 16:11:27 -04001485 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1486 called with the wrong number of arguments or a non-:py:obj:`int`
1487 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001488 """
1489 cert = X509()
1490 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1491 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1492 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1493
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001494 def test_gmtime_adj_notAfter(self):
1495 """
Alex Gaynor31287502015-09-05 16:11:27 -04001496 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1497 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001498 """
1499 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001500 not_after_min = (
1501 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1502 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001503 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001504 not_after = datetime.strptime(
1505 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1506 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001507 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1508 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001509
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001510 def test_has_expired_wrong_args(self):
1511 """
Alex Gaynor31287502015-09-05 16:11:27 -04001512 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1513 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001514 """
1515 cert = X509()
1516 self.assertRaises(TypeError, cert.has_expired, None)
1517
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001518 def test_has_expired(self):
1519 """
Alex Gaynor31287502015-09-05 16:11:27 -04001520 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1521 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001522 """
1523 cert = X509()
1524 cert.gmtime_adj_notAfter(-1)
1525 self.assertTrue(cert.has_expired())
1526
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001527 def test_has_not_expired(self):
1528 """
Alex Gaynor31287502015-09-05 16:11:27 -04001529 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1530 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001531 """
1532 cert = X509()
1533 cert.gmtime_adj_notAfter(2)
1534 self.assertFalse(cert.has_expired())
1535
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001536 def test_root_has_not_expired(self):
1537 """
Alex Gaynor31287502015-09-05 16:11:27 -04001538 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1539 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001540 """
1541 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1542 self.assertFalse(cert.has_expired())
1543
Rick Dean38a05c82009-07-18 01:41:30 -05001544 def test_digest(self):
1545 """
Alex Gaynor31287502015-09-05 16:11:27 -04001546 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1547 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001548 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001549 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001550 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001551 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1552 # actually matters to the assertion (ie, another arbitrary, good
1553 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001554 # Digest verified with the command:
1555 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001556 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001557 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001558
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001559 def _extcert(self, pkey, extensions):
1560 cert = X509()
1561 cert.set_pubkey(pkey)
1562 cert.get_subject().commonName = "Unit Tests"
1563 cert.get_issuer().commonName = "Unit Tests"
1564 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1565 cert.set_notBefore(when)
1566 cert.set_notAfter(when)
1567
1568 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001569 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001570 return load_certificate(
1571 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1572
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001573 def test_extension_count(self):
1574 """
Alex Gaynor31287502015-09-05 16:11:27 -04001575 :py:obj:`X509.get_extension_count` returns the number of extensions
1576 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001577 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001578 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001579 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1580 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001581 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001582 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001583
1584 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001585 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001586 self.assertEqual(c.get_extension_count(), 0)
1587
1588 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001589 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001590 self.assertEqual(c.get_extension_count(), 1)
1591
1592 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001593 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001594 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001595
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001596 def test_get_extension(self):
1597 """
Alex Gaynor31287502015-09-05 16:11:27 -04001598 :py:obj:`X509.get_extension` takes an integer and returns an
1599 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001600 """
1601 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001602 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1603 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001604 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001605 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001606
1607 cert = self._extcert(pkey, [ca, key, subjectAltName])
1608
1609 ext = cert.get_extension(0)
1610 self.assertTrue(isinstance(ext, X509Extension))
1611 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001612 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001613
1614 ext = cert.get_extension(1)
1615 self.assertTrue(isinstance(ext, X509Extension))
1616 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001617 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001618
1619 ext = cert.get_extension(2)
1620 self.assertTrue(isinstance(ext, X509Extension))
1621 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001622 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001623
1624 self.assertRaises(IndexError, cert.get_extension, -1)
1625 self.assertRaises(IndexError, cert.get_extension, 4)
1626 self.assertRaises(TypeError, cert.get_extension, "hello")
1627
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001628 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001629 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001630 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001631 bytes and this value is reflected in the string representation of the
1632 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001633 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001634 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001635
1636 ext = cert.get_extension(3)
1637 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001638 self.assertEqual(
1639 b("DNS:altnull.python.org\x00example.com, "
1640 "email:null@python.org\x00user@example.org, "
1641 "URI:http://null.python.org\x00http://example.org, "
1642 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1643 b(str(ext)))
1644
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001645 def test_invalid_digest_algorithm(self):
1646 """
Alex Gaynor31287502015-09-05 16:11:27 -04001647 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1648 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001649 """
1650 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001651 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001652
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001653 def test_get_subject_wrong_args(self):
1654 """
Alex Gaynor31287502015-09-05 16:11:27 -04001655 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1656 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001657 """
1658 cert = X509()
1659 self.assertRaises(TypeError, cert.get_subject, None)
1660
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001661 def test_get_subject(self):
1662 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001663 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001664 """
1665 cert = load_certificate(FILETYPE_PEM, self.pemData)
1666 subj = cert.get_subject()
1667 self.assertTrue(isinstance(subj, X509Name))
1668 self.assertEquals(
1669 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001670 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1671 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001672
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001673 def test_set_subject_wrong_args(self):
1674 """
Alex Gaynor31287502015-09-05 16:11:27 -04001675 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1676 the wrong number of arguments or an argument not of type
1677 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001678 """
1679 cert = X509()
1680 self.assertRaises(TypeError, cert.set_subject)
1681 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001682 with pytest.raises(TypeError):
1683 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001684
1685 def test_set_subject(self):
1686 """
Alex Gaynor31287502015-09-05 16:11:27 -04001687 :py:obj:`X509.set_subject` changes the subject of the certificate to
1688 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001689 """
1690 cert = X509()
1691 name = cert.get_subject()
1692 name.C = 'AU'
1693 name.O = 'Unit Tests'
1694 cert.set_subject(name)
1695 self.assertEquals(
1696 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001697 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001698
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001699 def test_get_issuer_wrong_args(self):
1700 """
Alex Gaynor31287502015-09-05 16:11:27 -04001701 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1702 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001703 """
1704 cert = X509()
1705 self.assertRaises(TypeError, cert.get_issuer, None)
1706
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001707 def test_get_issuer(self):
1708 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001709 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001710 """
1711 cert = load_certificate(FILETYPE_PEM, self.pemData)
1712 subj = cert.get_issuer()
1713 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001714 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001715 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001716 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001717 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1718 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001719
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001720 def test_set_issuer_wrong_args(self):
1721 """
Alex Gaynor31287502015-09-05 16:11:27 -04001722 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1723 the wrong number of arguments or an argument not of type
1724 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001725 """
1726 cert = X509()
1727 self.assertRaises(TypeError, cert.set_issuer)
1728 self.assertRaises(TypeError, cert.set_issuer, None)
1729 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1730
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001731 def test_set_issuer(self):
1732 """
Alex Gaynor31287502015-09-05 16:11:27 -04001733 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1734 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001735 """
1736 cert = X509()
1737 name = cert.get_issuer()
1738 name.C = 'AU'
1739 name.O = 'Unit Tests'
1740 cert.set_issuer(name)
1741 self.assertEquals(
1742 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001743 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001744
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001745 def test_get_pubkey_uninitialized(self):
1746 """
Alex Gaynor31287502015-09-05 16:11:27 -04001747 When called on a certificate with no public key,
1748 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001749 """
1750 cert = X509()
1751 self.assertRaises(Error, cert.get_pubkey)
1752
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001753 def test_subject_name_hash_wrong_args(self):
1754 """
Alex Gaynor31287502015-09-05 16:11:27 -04001755 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1756 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001757 """
1758 cert = X509()
1759 self.assertRaises(TypeError, cert.subject_name_hash, None)
1760
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001761 def test_subject_name_hash(self):
1762 """
Alex Gaynor31287502015-09-05 16:11:27 -04001763 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1764 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001765 """
1766 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001767 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001768 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001769 [3350047874, # OpenSSL 0.9.8, MD5
1770 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001771 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001772
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001773 def test_get_signature_algorithm(self):
1774 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001775 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001776 the algorithm used to sign the certificate.
1777 """
1778 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001779 self.assertEqual(
1780 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001781
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001782 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001783 """
Alex Gaynor31287502015-09-05 16:11:27 -04001784 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1785 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001786 """
1787 # This certificate has been modified to indicate a bogus OID in the
1788 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001789 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001790-----BEGIN CERTIFICATE-----
1791MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1792EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1793cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1794MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1795EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1796CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1797AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1798+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1799hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1800BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1801FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1802dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1803aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1804MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1805jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1806PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1807tgI5
1808-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001809""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001810 cert = load_certificate(FILETYPE_PEM, certPEM)
1811 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001812
1813
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001814class X509StoreTests(TestCase):
1815 """
1816 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1817 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001818
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001819 def test_type(self):
1820 """
1821 :py:obj:`X509StoreType` is a type object.
1822 """
1823 self.assertIdentical(X509Store, X509StoreType)
1824 self.assertConsistentType(X509Store, 'X509Store')
1825
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001826 def test_add_cert_wrong_args(self):
1827 store = X509Store()
1828 self.assertRaises(TypeError, store.add_cert)
1829 self.assertRaises(TypeError, store.add_cert, object())
1830 self.assertRaises(TypeError, store.add_cert, X509(), object())
1831
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001832 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001833 """
1834 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1835 certificate store.
1836 """
1837 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001838 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001839 store.add_cert(cert)
1840
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001841 def test_add_cert_rejects_duplicate(self):
1842 """
Alex Gaynor31287502015-09-05 16:11:27 -04001843 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1844 an attempt is made to add the same certificate to the store more than
1845 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001846 """
1847 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1848 store = X509Store()
1849 store.add_cert(cert)
1850 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001851
1852
Rick Dean623ee362009-07-17 12:22:16 -05001853class PKCS12Tests(TestCase):
1854 """
Alex Gaynor31287502015-09-05 16:11:27 -04001855 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1856 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001857 """
1858 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1859
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001860 def test_type(self):
1861 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001862 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001863 """
1864 self.assertIdentical(PKCS12, PKCS12Type)
1865 self.assertConsistentType(PKCS12, 'PKCS12')
1866
Rick Deanf94096c2009-07-18 14:23:06 -05001867 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001868 """
Alex Gaynor31287502015-09-05 16:11:27 -04001869 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1870 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001871 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001872 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001873 self.assertEqual(None, p12.get_certificate())
1874 self.assertEqual(None, p12.get_privatekey())
1875 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001876 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001877
1878 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001879 """
Alex Gaynor31287502015-09-05 16:11:27 -04001880 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1881 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1882 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1883 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001884 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001885 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001886 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001887 self.assertRaises(TypeError, p12.set_certificate, PKey())
1888 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001889 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001890 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1891 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001892 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1893 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1894 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001895 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001896 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1897 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001898
1899 def test_key_only(self):
1900 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001901 A :py:obj:`PKCS12` with only a private key 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 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001907 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05001908 self.assertEqual(None, p12.get_certificate())
1909 self.assertEqual(pkey, 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_ca_certificates())
1919 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001920
1921 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1922 # future this will be improved.
1923 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05001924
1925 def test_cert_only(self):
1926 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001927 A :py:obj:`PKCS12` with only a certificate can be exported using
1928 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001929 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001930 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001931 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001932 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001933 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05001934 self.assertEqual(cert, p12.get_certificate())
1935 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001936 try:
1937 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1938 except Error:
1939 # Some versions of OpenSSL will throw an exception
1940 # for this nearly useless PKCS12 we tried to generate:
1941 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1942 return
Rick Dean623ee362009-07-17 12:22:16 -05001943 p12 = load_pkcs12(dumped_p12, passwd)
1944 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001945
1946 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
1947 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1948
1949 # Oh ho. It puts the certificate into the ca certificates list, in
1950 # fact. Totally bogus, I would think. Nevertheless, let's exploit
1951 # that to check to see if it reconstructed the certificate we expected
1952 # it to. At some point, hopefully this will change so that
1953 # p12.get_certificate() is actually what returns the loaded
1954 # certificate.
1955 self.assertEqual(
1956 cleartextCertificatePEM,
1957 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05001958
Alex Gaynor31287502015-09-05 16:11:27 -04001959 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
1960 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05001961 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001962 Generate a PKCS12 object with components from PEM. Verify that the set
1963 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05001964 """
Rick Deanf94096c2009-07-18 14:23:06 -05001965 p12 = PKCS12()
1966 if cert_pem:
1967 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1968 self.assertEqual(ret, None)
1969 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001970 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05001971 self.assertEqual(ret, None)
1972 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04001973 ret = p12.set_ca_certificates(
1974 (load_certificate(FILETYPE_PEM, ca_pem),)
1975 )
Rick Deanf94096c2009-07-18 14:23:06 -05001976 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001977 if friendly_name:
1978 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05001979 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05001980 return p12
1981
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001982 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001983 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05001984 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001985 Use openssl program to confirm three components are recoverable from a
1986 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05001987 """
1988 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001989 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001990 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
1991 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001992 self.assertEqual(recovered_key[-len(key):], key)
1993 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001994 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001995 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
1996 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001997 self.assertEqual(recovered_cert[-len(cert):], cert)
1998 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001999 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002000 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2001 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002002 self.assertEqual(recovered_cert[-len(ca):], ca)
2003
Stephen Holsapple38482622014-04-05 20:29:34 -07002004 def verify_pkcs12_container(self, p12):
2005 """
2006 Verify that the PKCS#12 container contains the correct client
2007 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002008
2009 :param p12: The PKCS12 instance to verify.
2010 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002011 """
2012 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2013 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002014 self.assertEqual(
2015 (client_cert_pem, client_key_pem, None),
2016 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002017
Rick Deanf94096c2009-07-18 14:23:06 -05002018 def test_load_pkcs12(self):
2019 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002020 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002021 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002022 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002023 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002024 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002025 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002026 pem,
2027 b"pkcs12",
2028 b"-export",
2029 b"-clcerts",
2030 b"-passout",
2031 b"pass:" + passwd
2032 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002033 p12 = load_pkcs12(p12_str, passphrase=passwd)
2034 self.verify_pkcs12_container(p12)
2035
Abraham Martinc5484ba2015-03-25 15:33:05 +00002036 def test_load_pkcs12_text_passphrase(self):
2037 """
2038 A PKCS12 string generated using the openssl command line can be loaded
2039 with :py:obj:`load_pkcs12` and its components extracted and examined.
2040 Using text as passphrase instead of bytes. DeprecationWarning expected.
2041 """
2042 pem = client_key_pem + client_cert_pem
2043 passwd = b"whatever"
2044 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2045 b"-passout", b"pass:" + passwd)
2046 with catch_warnings(record=True) as w:
2047 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002048 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002049
2050 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002051 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002052 WARNING_TYPE_EXPECTED
2053 ),
2054 str(w[-1].message)
2055 )
2056 self.assertIs(w[-1].category, DeprecationWarning)
2057
Abraham Martinc5484ba2015-03-25 15:33:05 +00002058 self.verify_pkcs12_container(p12)
2059
Stephen Holsapple38482622014-04-05 20:29:34 -07002060 def test_load_pkcs12_no_passphrase(self):
2061 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002062 A PKCS12 string generated using openssl command line can be loaded with
2063 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2064 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002065 """
2066 pem = client_key_pem + client_cert_pem
2067 p12_str = _runopenssl(
2068 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2069 p12 = load_pkcs12(p12_str)
2070 self.verify_pkcs12_container(p12)
2071
Stephen Holsapple38482622014-04-05 20:29:34 -07002072 def _dump_and_load(self, dump_passphrase, load_passphrase):
2073 """
2074 A helper method to dump and load a PKCS12 object.
2075 """
2076 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2077 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2078 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2079
Stephen Holsapple38482622014-04-05 20:29:34 -07002080 def test_load_pkcs12_null_passphrase_load_empty(self):
2081 """
2082 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002083 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002084 extracted and examined.
2085 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002086 self.verify_pkcs12_container(
2087 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002088
Stephen Holsapple38482622014-04-05 20:29:34 -07002089 def test_load_pkcs12_null_passphrase_load_null(self):
2090 """
2091 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002092 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002093 extracted and examined.
2094 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002095 self.verify_pkcs12_container(
2096 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002097
Stephen Holsapple38482622014-04-05 20:29:34 -07002098 def test_load_pkcs12_empty_passphrase_load_empty(self):
2099 """
2100 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002101 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002102 extracted and examined.
2103 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002104 self.verify_pkcs12_container(
2105 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002106
Stephen Holsapple38482622014-04-05 20:29:34 -07002107 def test_load_pkcs12_empty_passphrase_load_null(self):
2108 """
2109 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002110 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002111 extracted and examined.
2112 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002113 self.verify_pkcs12_container(
2114 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002115
Rick Deanee568302009-07-24 09:56:29 -05002116 def test_load_pkcs12_garbage(self):
2117 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002118 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2119 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002120 """
2121 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002122 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002123 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2124 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002125
Rick Deanf94096c2009-07-18 14:23:06 -05002126 def test_replace(self):
2127 """
Alex Gaynor31287502015-09-05 16:11:27 -04002128 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2129 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002130 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002131 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002132 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2133 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2134 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002135 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002136 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002137 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002138 self.assertEqual(1, len(p12.get_ca_certificates()))
2139 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002140 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002141 self.assertEqual(2, len(p12.get_ca_certificates()))
2142 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2143 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2144
Rick Deanf94096c2009-07-18 14:23:06 -05002145 def test_friendly_name(self):
2146 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002147 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002148 :py:obj:`PKCS12.get_friendlyname` and
2149 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2150 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002151 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002152 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002153 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002154 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002155 p12.set_friendlyname(friendly_name)
2156 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002157 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002158 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002159 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002160 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002161 # We would use the openssl program to confirm the friendly
2162 # name, but it is not possible. The pkcs12 command
2163 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002164 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002165 self.check_recovery(
2166 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2167 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002168
Rick Deanf94096c2009-07-18 14:23:06 -05002169 def test_various_empty_passphrases(self):
2170 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002171 Test that missing, None, and '' passphrases are identical for PKCS12
2172 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002173 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002174 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002175 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002176 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2177 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2178 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2179 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2180 self.check_recovery(
2181 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2182 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002183
Rick Deanf94096c2009-07-18 14:23:06 -05002184 def test_removing_ca_cert(self):
2185 """
Alex Gaynor31287502015-09-05 16:11:27 -04002186 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2187 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002188 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002189 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2190 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002191 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002192
Rick Deanf94096c2009-07-18 14:23:06 -05002193 def test_export_without_mac(self):
2194 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002195 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002196 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002197 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002198 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002199 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002200 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002201 self.check_recovery(
2202 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002203 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002204
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002205 def test_load_without_mac(self):
2206 """
2207 Loading a PKCS12 without a MAC does something other than crash.
2208 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002209 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002210 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2211 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002212 try:
2213 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2214 # The person who generated this PCKS12 should be flogged,
2215 # or better yet we should have a means to determine
2216 # whether a PCKS12 had a MAC that was verified.
2217 # Anyway, libopenssl chooses to allow it, so the
2218 # pyopenssl binding does as well.
2219 self.assertTrue(isinstance(recovered_p12, PKCS12))
2220 except Error:
2221 # Failing here with an exception is preferred as some openssl
2222 # versions do.
2223 pass
Rick Dean623ee362009-07-17 12:22:16 -05002224
Rick Dean25bcc1f2009-07-20 11:53:13 -05002225 def test_zero_len_list_for_ca(self):
2226 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002227 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002228 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002229 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002230 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002231 p12.set_ca_certificates([])
2232 self.assertEqual((), p12.get_ca_certificates())
2233 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2234 self.check_recovery(
2235 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2236 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002237
Rick Deanf94096c2009-07-18 14:23:06 -05002238 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002239 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002240 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002241 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002242 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002243 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002244 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002245 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002246
Abraham Martinc5484ba2015-03-25 15:33:05 +00002247 def test_export_without_bytes(self):
2248 """
2249 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2250 """
2251 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2252
2253 with catch_warnings(record=True) as w:
2254 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002255 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002256 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002257 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002258 WARNING_TYPE_EXPECTED
2259 ),
2260 str(w[-1].message)
2261 )
2262 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002263 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002264 dumped_p12,
2265 key=server_key_pem,
2266 cert=server_cert_pem,
2267 passwd=b"randomtext"
2268 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002269
Rick Deanf94096c2009-07-18 14:23:06 -05002270 def test_key_cert_mismatch(self):
2271 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002272 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002273 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002274 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002275 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2276 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002277
2278
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002279# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002280_cmdLineQuoteRe = re.compile(br'(\\*)"')
2281_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002282
2283
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002284def cmdLineQuote(s):
2285 """
2286 Internal method for quoting a single command-line argument.
2287
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002288 See http://www.perlmonks.org/?node_id=764004
2289
Jonathan Ballet648875f2011-07-16 14:14:58 +09002290 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002291 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002292 cmd.exe-style quoting
2293
Jonathan Ballet648875f2011-07-16 14:14:58 +09002294 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002295 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002296 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002297 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2298 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002299
2300
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002301def quoteArguments(arguments):
2302 """
2303 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002304 a similar API. This allows the list passed to
2305 :py:obj:`reactor.spawnProcess` to match the child process's
2306 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002307
Jonathan Ballet648875f2011-07-16 14:14:58 +09002308 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002309 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002310
Jonathan Ballet648875f2011-07-16 14:14:58 +09002311 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002312 :return: A space-delimited string containing quoted versions of
2313 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002314 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002315 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002316
2317
Rick Dean4c9ad612009-07-17 15:05:22 -05002318def _runopenssl(pem, *args):
2319 """
2320 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002321 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002322 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002323 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002324 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002325 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2326 for arg in args
2327 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002328 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002329 command = b"openssl " + quoteArguments(args)
2330 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002331 proc.stdin.write(pem)
2332 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002333 output = proc.stdout.read()
2334 proc.stdout.close()
2335 proc.wait()
2336 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002337
2338
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002339class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002340 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002341 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002342 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002343
2344 def test_load_privatekey_invalid_format(self):
2345 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002346 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2347 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002348 """
2349 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2350
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002351 def test_load_privatekey_invalid_passphrase_type(self):
2352 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002353 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2354 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002355 """
2356 self.assertRaises(
2357 TypeError,
2358 load_privatekey,
2359 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2360
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002361 def test_load_privatekey_wrong_args(self):
2362 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002363 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2364 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002365 """
2366 self.assertRaises(TypeError, load_privatekey)
2367
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002368 def test_load_privatekey_wrongPassphrase(self):
2369 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002370 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2371 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002372 """
2373 self.assertRaises(
2374 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002375 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002376
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002377 def test_load_privatekey_passphraseWrongType(self):
2378 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002379 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2380 a passphrase with a private key encoded in a format, that doesn't
2381 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002382 """
2383 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2384 blob = dump_privatekey(FILETYPE_ASN1, key)
2385 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002386 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002387
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002388 def test_load_privatekey_passphrase(self):
2389 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002390 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2391 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002392 """
2393 key = load_privatekey(
2394 FILETYPE_PEM, encryptedPrivateKeyPEM,
2395 encryptedPrivateKeyPEMPassphrase)
2396 self.assertTrue(isinstance(key, PKeyType))
2397
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002398 def test_load_privatekey_passphrase_exception(self):
2399 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002400 If the passphrase callback raises an exception, that exception is
2401 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002402 """
2403 def cb(ignored):
2404 raise ArithmeticError
2405
Alex Gaynor791212d2015-09-05 15:46:08 -04002406 with pytest.raises(ArithmeticError):
2407 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002408
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002409 def test_load_privatekey_wrongPassphraseCallback(self):
2410 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002411 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2412 is passed an encrypted PEM and a passphrase callback which returns an
2413 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002414 """
2415 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002416
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002417 def cb(*a):
2418 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002419 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002420 self.assertRaises(
2421 Error,
2422 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2423 self.assertTrue(called)
2424
2425 def test_load_privatekey_passphraseCallback(self):
2426 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002427 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2428 encrypted PEM string if given a passphrase callback which returns the
2429 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002430 """
2431 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002432
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002433 def cb(writing):
2434 called.append(writing)
2435 return encryptedPrivateKeyPEMPassphrase
2436 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2437 self.assertTrue(isinstance(key, PKeyType))
2438 self.assertEqual(called, [False])
2439
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002440 def test_load_privatekey_passphrase_wrong_return_type(self):
2441 """
2442 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2443 callback returns something other than a byte string.
2444 """
2445 self.assertRaises(
2446 ValueError,
2447 load_privatekey,
2448 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2449
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002450 def test_dump_privatekey_wrong_args(self):
2451 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002452 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2453 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002454 """
2455 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002456 # If cipher name is given, password is required.
2457 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002458 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002459
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002460 def test_dump_privatekey_unknown_cipher(self):
2461 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002462 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2463 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002464 """
2465 key = PKey()
2466 key.generate_key(TYPE_RSA, 512)
2467 self.assertRaises(
2468 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002469 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002470
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002471 def test_dump_privatekey_invalid_passphrase_type(self):
2472 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002473 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2474 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002475 """
2476 key = PKey()
2477 key.generate_key(TYPE_RSA, 512)
2478 self.assertRaises(
2479 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002480 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002481
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002482 def test_dump_privatekey_invalid_filetype(self):
2483 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002484 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2485 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002486 """
2487 key = PKey()
2488 key.generate_key(TYPE_RSA, 512)
2489 self.assertRaises(ValueError, dump_privatekey, 100, key)
2490
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002491 def test_load_privatekey_passphraseCallbackLength(self):
2492 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002493 :py:obj:`crypto.load_privatekey` should raise an error when the
2494 passphrase provided by the callback is too long, not silently truncate
2495 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002496 """
2497 def cb(ignored):
2498 return "a" * 1025
2499
Alex Gaynor791212d2015-09-05 15:46:08 -04002500 with pytest.raises(ValueError):
2501 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002502
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002503 def test_dump_privatekey_passphrase(self):
2504 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002505 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2506 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002507 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002508 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002509 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002510 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2511 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002512 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2513 self.assertTrue(isinstance(loadedKey, PKeyType))
2514 self.assertEqual(loadedKey.type(), key.type())
2515 self.assertEqual(loadedKey.bits(), key.bits())
2516
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002517 def test_dump_privatekey_passphraseWrongType(self):
2518 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002519 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2520 a passphrase with a private key encoded in a format, that doesn't
2521 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002522 """
2523 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002524 with pytest.raises(ValueError):
2525 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002526
Rick Dean5b7b6372009-04-01 11:34:06 -05002527 def test_dump_certificate(self):
2528 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002529 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002530 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002531 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002532 cert = load_certificate(FILETYPE_PEM, pemData)
2533 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2534 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2535 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002536 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002537 self.assertEqual(dumped_der, good_der)
2538 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2539 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2540 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2541 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002542 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002543 self.assertEqual(dumped_text, good_text)
2544
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002545 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002546 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002547 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002548 """
2549 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002550 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002551 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2552 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002553
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002554 def test_dump_privatekey_asn1(self):
2555 """
2556 :py:obj:`dump_privatekey` writes a DER
2557 """
2558 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2559 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2560
Rick Dean5b7b6372009-04-01 11:34:06 -05002561 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002562 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002563 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002564 self.assertEqual(dumped_der, good_der)
2565 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2566 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2567 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002568
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002569 def test_dump_privatekey_text(self):
2570 """
2571 :py:obj:`dump_privatekey` writes a text
2572 """
2573 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2574 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2575
Rick Dean5b7b6372009-04-01 11:34:06 -05002576 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002577 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002578 self.assertEqual(dumped_text, good_text)
2579
Cory Benfield6492f7c2015-10-27 16:57:58 +09002580 def test_dump_publickey_pem(self):
2581 """
Cory Benfield11c10192015-10-27 17:23:03 +09002582 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002583 """
2584 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2585 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002586 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002587
2588 def test_dump_publickey_asn1(self):
2589 """
Cory Benfield11c10192015-10-27 17:23:03 +09002590 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002591 """
2592 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2593 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2594 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2595 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002596 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002597
Cory Benfielde02c7d82015-10-27 17:34:49 +09002598 def test_dump_publickey_invalid_type(self):
2599 """
2600 dump_publickey doesn't support FILETYPE_TEXT.
2601 """
2602 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2603
2604 with pytest.raises(ValueError):
2605 dump_publickey(FILETYPE_TEXT, key)
2606
2607 def test_load_publickey_invalid_type(self):
2608 """
2609 load_publickey doesn't support FILETYPE_TEXT.
2610 """
2611 with pytest.raises(ValueError):
2612 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2613
2614 def test_load_publickey_invalid_key_format(self):
2615 """
2616 load_publickey explodes on incorrect keys.
2617 """
2618 with pytest.raises(Error):
2619 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2620
2621 def test_load_publickey_tolerates_unicode_strings(self):
2622 """
2623 load_publickey works with text strings, not just bytes.
2624 """
2625 serialized = cleartextPublicKeyPEM.decode('ascii')
2626 key = load_publickey(FILETYPE_PEM, serialized)
2627 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2628 assert dumped_pem == cleartextPublicKeyPEM
2629
Rick Dean5b7b6372009-04-01 11:34:06 -05002630 def test_dump_certificate_request(self):
2631 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002632 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002633 """
Alex Gaynor31287502015-09-05 16:11:27 -04002634 req = load_certificate_request(
2635 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002636 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2637 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2638 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002639 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002640 self.assertEqual(dumped_der, good_der)
2641 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2642 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2643 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2644 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002645 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002646 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002647 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002648
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002649 def test_dump_privatekey_passphraseCallback(self):
2650 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002651 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2652 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002653 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002654 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002655 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002656
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002657 def cb(writing):
2658 called.append(writing)
2659 return passphrase
2660 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002661 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2662 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002663 self.assertEqual(called, [True])
2664 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2665 self.assertTrue(isinstance(loadedKey, PKeyType))
2666 self.assertEqual(loadedKey.type(), key.type())
2667 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002668
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002669 def test_dump_privatekey_passphrase_exception(self):
2670 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002671 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002672 by the passphrase callback.
2673 """
2674 def cb(ignored):
2675 raise ArithmeticError
2676
2677 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002678 with pytest.raises(ArithmeticError):
2679 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002680
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002681 def test_dump_privatekey_passphraseCallbackLength(self):
2682 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002683 :py:obj:`crypto.dump_privatekey` should raise an error when the
2684 passphrase provided by the callback is too long, not silently truncate
2685 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002686 """
2687 def cb(ignored):
2688 return "a" * 1025
2689
2690 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002691 with pytest.raises(ValueError):
2692 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002693
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002694 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002695 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002696 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2697 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002698 """
2699 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2700 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2701
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002702 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002703 """
2704 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2705 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2706 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002707 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2708 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2709
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002710 def test_load_pkcs7_data_invalid(self):
2711 """
2712 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2713 :py:obj:`Error` is raised.
2714 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002715 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002716
2717
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002718class LoadCertificateTests(TestCase):
2719 """
2720 Tests for :py:obj:`load_certificate_request`.
2721 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002722
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002723 def test_badFileType(self):
2724 """
2725 If the file type passed to :py:obj:`load_certificate_request` is
2726 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2727 :py:class:`ValueError` is raised.
2728 """
2729 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2730
2731
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002732class PKCS7Tests(TestCase):
2733 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002734 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002735 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002736
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002737 def test_type(self):
2738 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002739 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002740 """
2741 self.assertTrue(isinstance(PKCS7Type, type))
2742 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2743
2744 # XXX This doesn't currently work.
2745 # self.assertIdentical(PKCS7, PKCS7Type)
2746
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002747 # XXX Opposite results for all these following methods
2748
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002749 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002750 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002751 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2752 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002753 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002754 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2755 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2756
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002757 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002758 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002759 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2760 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002761 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002762 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2763 self.assertTrue(pkcs7.type_is_signed())
2764
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002765 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002766 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002767 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2768 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002769 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002770 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2771 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2772
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002773 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002774 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002775 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2776 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002777 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002778 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2779 self.assertFalse(pkcs7.type_is_enveloped())
2780
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002781 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002782 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002783 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2784 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002785 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002786 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2787 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2788
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002789 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002790 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002791 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2792 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002793 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002794 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2795 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2796
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002797 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002798 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002799 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2800 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002801 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002802 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2803 self.assertFalse(pkcs7.type_is_data())
2804
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002805 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002806 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002807 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2808 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002809 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002810 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2811 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2812
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002813 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002814 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002815 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2816 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002817 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002818 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2819 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2820
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002821 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002822 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002823 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2824 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002825 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002826 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002827 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002828
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002829 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002830 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002831 If an attribute other than one of the methods tested here is accessed
2832 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2833 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002834 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002835 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2836 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2837
2838
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002839class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002840 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002841 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002842 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002843
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002844 def signable(self):
2845 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002846 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002847 """
2848 return NetscapeSPKI()
2849
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002850 def test_type(self):
2851 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002852 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2853 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002854 """
2855 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2856 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2857
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002858 def test_construction(self):
2859 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002860 :py:obj:`NetscapeSPKI` returns an instance of
2861 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002862 """
2863 nspki = NetscapeSPKI()
2864 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2865
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002866 def test_invalid_attribute(self):
2867 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002868 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2869 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002870 """
2871 nspki = NetscapeSPKI()
2872 self.assertRaises(AttributeError, lambda: nspki.foo)
2873
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002874 def test_b64_encode(self):
2875 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002876 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2877 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002878 """
2879 nspki = NetscapeSPKI()
2880 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002881 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002882
2883
Rick Dean536ba022009-07-24 23:57:27 -05002884class RevokedTests(TestCase):
2885 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002886 Tests for :py:obj:`OpenSSL.crypto.Revoked`
Rick Dean536ba022009-07-24 23:57:27 -05002887 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002888
Rick Dean536ba022009-07-24 23:57:27 -05002889 def test_construction(self):
2890 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002891 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002892 that it is empty.
2893 """
2894 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002895 self.assertTrue(isinstance(revoked, Revoked))
2896 self.assertEquals(type(revoked), Revoked)
2897 self.assertEquals(revoked.get_serial(), b('00'))
2898 self.assertEquals(revoked.get_rev_date(), None)
2899 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05002900
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002901 def test_construction_wrong_args(self):
2902 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002903 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
2904 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002905 """
2906 self.assertRaises(TypeError, Revoked, None)
2907 self.assertRaises(TypeError, Revoked, 1)
2908 self.assertRaises(TypeError, Revoked, "foo")
2909
Rick Dean536ba022009-07-24 23:57:27 -05002910 def test_serial(self):
2911 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002912 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002913 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002914 with grace.
2915 """
2916 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002917 ret = revoked.set_serial(b('10b'))
2918 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002919 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002920 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05002921
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002922 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05002923 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002924 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05002925
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002926 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05002927 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002928 self.assertRaises(TypeError, revoked.get_serial, 1)
2929 self.assertRaises(TypeError, revoked.get_serial, None)
2930 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05002931
Rick Dean536ba022009-07-24 23:57:27 -05002932 def test_date(self):
2933 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002934 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002935 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002936 with grace.
2937 """
2938 revoked = Revoked()
2939 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002940 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05002941
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002942 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002943 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002944 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002945 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002946 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05002947
Rick Dean6385faf2009-07-26 00:07:47 -05002948 def test_reason(self):
2949 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002950 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002951 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05002952 as "set". Likewise, each reason of all_reasons() must work.
2953 """
2954 revoked = Revoked()
2955 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002956 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05002957 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002958 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05002959 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002960 self.assertEquals(
2961 reason.lower().replace(b(' '), b('')),
2962 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002963 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05002964
2965 revoked.set_reason(None)
2966 self.assertEqual(revoked.get_reason(), None)
2967
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002968 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05002969 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002970 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002971 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002972 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05002973 """
2974 revoked = Revoked()
2975 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04002976 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05002977
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002978 def test_get_reason_wrong_arguments(self):
2979 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002980 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
2981 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002982 """
2983 revoked = Revoked()
2984 self.assertRaises(TypeError, revoked.get_reason, None)
2985 self.assertRaises(TypeError, revoked.get_reason, 1)
2986 self.assertRaises(TypeError, revoked.get_reason, "foo")
2987
2988
Rick Dean536ba022009-07-24 23:57:27 -05002989class CRLTests(TestCase):
2990 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002991 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05002992 """
2993 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2994 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2995
2996 def test_construction(self):
2997 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002998 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002999 that it is empty
3000 """
3001 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003002 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003003 self.assertEqual(crl.get_revoked(), None)
3004
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003005 def test_construction_wrong_args(self):
3006 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003007 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3008 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003009 """
3010 self.assertRaises(TypeError, CRL, 1)
3011 self.assertRaises(TypeError, CRL, "")
3012 self.assertRaises(TypeError, CRL, None)
3013
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003014 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003015 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003016 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003017 """
3018 crl = CRL()
3019 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003020 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003021 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003022 revoked.set_serial(b('3ab'))
3023 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003024 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003025 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003026
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003027 def test_export_pem(self):
3028 """
3029 If not passed a format, ``CRL.export`` returns a "PEM" format string
3030 representing a serial number, a revoked reason, and certificate issuer
3031 information.
3032 """
3033 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003034 # PEM format
3035 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003036 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003037
3038 # These magic values are based on the way the CRL above was constructed
3039 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003040 text.index(b('Serial Number: 03AB'))
3041 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003042 text.index(
3043 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3044 )
3045
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003046 def test_export_der(self):
3047 """
3048 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3049 "DER" format string representing a serial number, a revoked reason, and
3050 certificate issuer information.
3051 """
3052 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003053
3054 # DER format
3055 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003056 text = _runopenssl(
3057 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3058 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003059 text.index(b('Serial Number: 03AB'))
3060 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003061 text.index(
3062 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3063 )
3064
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003065 def test_export_text(self):
3066 """
3067 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3068 text format string like the one produced by the openssl command line
3069 tool.
3070 """
3071 crl = self._get_crl()
3072
3073 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3074 text = _runopenssl(
3075 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3076 )
Rick Dean536ba022009-07-24 23:57:27 -05003077
3078 # text format
3079 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3080 self.assertEqual(text, dumped_text)
3081
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003082 def test_export_custom_digest(self):
3083 """
3084 If passed the name of a digest function, ``CRL.export`` uses a
3085 signature algorithm based on that digest function.
3086 """
3087 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003088 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003089 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3090 text.index(b('Signature Algorithm: sha1'))
3091
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003092 def test_export_md5_digest(self):
3093 """
3094 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3095 not emit a deprecation warning.
3096 """
3097 crl = self._get_crl()
3098 with catch_warnings(record=True) as catcher:
3099 simplefilter("always")
3100 self.assertEqual(0, len(catcher))
3101 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3102 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3103 text.index(b('Signature Algorithm: md5'))
3104
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003105 def test_export_default_digest(self):
3106 """
3107 If not passed the name of a digest function, ``CRL.export`` uses a
3108 signature algorithm based on MD5 and emits a deprecation warning.
3109 """
3110 crl = self._get_crl()
3111 with catch_warnings(record=True) as catcher:
3112 simplefilter("always")
3113 dumped_crl = crl.export(self.cert, self.pkey)
3114 self.assertEqual(
3115 "The default message digest (md5) is deprecated. "
3116 "Pass the name of a message digest explicitly.",
3117 str(catcher[0].message),
3118 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003119 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3120 text.index(b('Signature Algorithm: md5'))
3121
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003122 def test_export_invalid(self):
3123 """
3124 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003125 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003126 """
3127 crl = CRL()
3128 self.assertRaises(Error, crl.export, X509(), PKey())
3129
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003130 def test_add_revoked_keyword(self):
3131 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003132 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003133 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003134 """
3135 crl = CRL()
3136 revoked = Revoked()
3137 crl.add_revoked(revoked=revoked)
3138 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3139
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003140 def test_export_wrong_args(self):
3141 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003142 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003143 four arguments, or with arguments other than the certificate,
3144 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003145 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003146 """
3147 crl = CRL()
3148 self.assertRaises(TypeError, crl.export)
3149 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003150 with pytest.raises(TypeError):
3151 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3152 with pytest.raises(TypeError):
3153 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3154 with pytest.raises(TypeError):
3155 crl.export(self.cert, None, FILETYPE_PEM, 10)
3156 with pytest.raises(TypeError):
3157 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003158 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3159
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003160 def test_export_unknown_filetype(self):
3161 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003162 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003163 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3164 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003165 """
3166 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003167 with pytest.raises(ValueError):
3168 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003169
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003170 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003171 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003172 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003173 in a :py:obj:`ValueError` being raised.
3174 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003175 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003176 self.assertRaises(
3177 ValueError,
3178 crl.export,
3179 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3180 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003181
Rick Dean536ba022009-07-24 23:57:27 -05003182 def test_get_revoked(self):
3183 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003184 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003185 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3186 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003187 """
3188 crl = CRL()
3189
3190 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003191 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003192 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003193 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003194 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003195 revoked.set_serial(b('100'))
3196 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003197 crl.add_revoked(revoked)
3198
3199 revs = crl.get_revoked()
3200 self.assertEqual(len(revs), 2)
3201 self.assertEqual(type(revs[0]), Revoked)
3202 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003203 self.assertEqual(revs[0].get_serial(), b('03AB'))
3204 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003205 self.assertEqual(revs[0].get_rev_date(), now)
3206 self.assertEqual(revs[1].get_rev_date(), now)
3207
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003208 def test_get_revoked_wrong_args(self):
3209 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003210 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3211 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003212 """
3213 crl = CRL()
3214 self.assertRaises(TypeError, crl.get_revoked, None)
3215 self.assertRaises(TypeError, crl.get_revoked, 1)
3216 self.assertRaises(TypeError, crl.get_revoked, "")
3217 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3218
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003219 def test_add_revoked_wrong_args(self):
3220 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003221 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3222 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003223 """
3224 crl = CRL()
3225 self.assertRaises(TypeError, crl.add_revoked)
3226 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3227 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3228
Rick Dean536ba022009-07-24 23:57:27 -05003229 def test_load_crl(self):
3230 """
3231 Load a known CRL and inspect its revocations. Both
3232 PEM and DER formats are loaded.
3233 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003234 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003235 revs = crl.get_revoked()
3236 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003237 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003238 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003239 self.assertEqual(revs[1].get_serial(), b('0100'))
3240 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003241
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003242 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003243 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003244 revs = crl.get_revoked()
3245 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003246 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003247 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003248 self.assertEqual(revs[1].get_serial(), b('0100'))
3249 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003250
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003251 def test_load_crl_wrong_args(self):
3252 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003253 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3254 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003255 """
3256 self.assertRaises(TypeError, load_crl)
3257 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3258 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3259
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003260 def test_load_crl_bad_filetype(self):
3261 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003262 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3263 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003264 """
3265 self.assertRaises(ValueError, load_crl, 100, crlData)
3266
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003267 def test_load_crl_bad_data(self):
3268 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003269 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3270 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003271 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003272 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003273
Dominic Chenf05b2122015-10-13 16:32:35 +00003274 def test_dump_crl(self):
3275 """
3276 The dumped CRL matches the original input.
3277 """
3278 crl = load_crl(FILETYPE_PEM, crlData)
3279 buf = dump_crl(FILETYPE_PEM, crl)
3280 assert buf == crlData
3281
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003282
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003283class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003284 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003285 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003286 """
3287 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3288 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003289 intermediate_server_cert = load_certificate(
3290 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003291
3292 def test_valid(self):
3293 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003294 :py:obj:`verify_certificate` returns ``None`` when called with a
3295 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003296 """
3297 store = X509Store()
3298 store.add_cert(self.root_cert)
3299 store.add_cert(self.intermediate_cert)
3300 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003301 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003302
3303 def test_reuse(self):
3304 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003305 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003306 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003307 """
3308 store = X509Store()
3309 store.add_cert(self.root_cert)
3310 store.add_cert(self.intermediate_cert)
3311 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003312 self.assertEqual(store_ctx.verify_certificate(), None)
3313 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003314
3315 def test_trusted_self_signed(self):
3316 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003317 :py:obj:`verify_certificate` returns ``None`` when called with a
3318 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003319 """
3320 store = X509Store()
3321 store.add_cert(self.root_cert)
3322 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003323 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003324
3325 def test_untrusted_self_signed(self):
3326 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003327 :py:obj:`verify_certificate` raises error when a self-signed
3328 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003329 """
3330 store = X509Store()
3331 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003332 with pytest.raises(X509StoreContextError) as exc:
3333 store_ctx.verify_certificate()
3334
3335 assert exc.value.args[0][2] == 'self signed certificate'
3336 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003337
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003338 def test_invalid_chain_no_root(self):
3339 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003340 :py:obj:`verify_certificate` raises error when a root certificate is
3341 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003342 """
3343 store = X509Store()
3344 store.add_cert(self.intermediate_cert)
3345 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003346
3347 with pytest.raises(X509StoreContextError) as exc:
3348 store_ctx.verify_certificate()
3349
3350 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3351 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003352
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003353 def test_invalid_chain_no_intermediate(self):
3354 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003355 :py:obj:`verify_certificate` raises error when an intermediate
3356 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003357 """
3358 store = X509Store()
3359 store.add_cert(self.root_cert)
3360 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003361
Alex Gaynor85b49702015-09-05 16:30:59 -04003362 with pytest.raises(X509StoreContextError) as exc:
3363 store_ctx.verify_certificate()
3364
3365 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3366 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003367
Stephen Holsapple46a09252015-02-12 14:45:43 -08003368 def test_modification_pre_verify(self):
3369 """
3370 :py:obj:`verify_certificate` can use a store context modified after
3371 instantiation.
3372 """
3373 store_bad = X509Store()
3374 store_bad.add_cert(self.intermediate_cert)
3375 store_good = X509Store()
3376 store_good.add_cert(self.root_cert)
3377 store_good.add_cert(self.intermediate_cert)
3378 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003379
3380 with pytest.raises(X509StoreContextError) as exc:
3381 store_ctx.verify_certificate()
3382
3383 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3384 assert exc.value.certificate.get_subject().CN == 'intermediate'
3385
Stephen Holsapple46a09252015-02-12 14:45:43 -08003386 store_ctx.set_store(store_good)
3387 self.assertEqual(store_ctx.verify_certificate(), None)
3388
3389
James Yonan7c2e5d32010-02-27 05:45:50 -07003390class SignVerifyTests(TestCase):
3391 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003392 Tests for :py:obj:`OpenSSL.crypto.sign` and
3393 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003394 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003395
James Yonan7c2e5d32010-02-27 05:45:50 -07003396 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003397 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003398 :py:obj:`sign` generates a cryptographic signature which
3399 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003400 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003401 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003402 "It was a bright cold day in April, and the clocks were striking "
3403 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3404 "effort to escape the vile wind, slipped quickly through the "
3405 "glass doors of Victory Mansions, though not quickly enough to "
3406 "prevent a swirl of gritty dust from entering along with him.")
3407
3408 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003409 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003410 # verify the content with this cert
3411 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3412 # certificate unrelated to priv_key, used to trigger an error
3413 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003414
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003415 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003416 sig = sign(priv_key, content, digest)
3417
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003418 # Verify the signature of content, will throw an exception if
3419 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003420 verify(good_cert, sig, content, digest)
3421
3422 # This should fail because the certificate doesn't match the
3423 # private key that was used to sign the content.
3424 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3425
3426 # This should fail because we've "tainted" the content after
3427 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003428 self.assertRaises(
3429 Error, verify,
3430 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003431
3432 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003433 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003434 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003435 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003436 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003437
Abraham Martinc5484ba2015-03-25 15:33:05 +00003438 def test_sign_verify_with_text(self):
3439 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003440 :py:obj:`sign` generates a cryptographic signature which
3441 :py:obj:`verify` can check. Deprecation warnings raised because using
3442 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003443 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003444 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003445 b"It was a bright cold day in April, and the clocks were striking "
3446 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3447 b"effort to escape the vile wind, slipped quickly through the "
3448 b"glass doors of Victory Mansions, though not quickly enough to "
3449 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003450 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003451
3452 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3453 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3454 for digest in ['md5', 'sha1']:
3455 with catch_warnings(record=True) as w:
3456 simplefilter("always")
3457 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003458
3459 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003460 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003461 WARNING_TYPE_EXPECTED
3462 ),
3463 str(w[-1].message)
3464 )
3465 self.assertIs(w[-1].category, DeprecationWarning)
3466
Abraham Martinc5484ba2015-03-25 15:33:05 +00003467 with catch_warnings(record=True) as w:
3468 simplefilter("always")
3469 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003470
3471 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003472 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003473 WARNING_TYPE_EXPECTED
3474 ),
3475 str(w[-1].message)
3476 )
3477 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003478
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003479 def test_sign_nulls(self):
3480 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003481 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003482 """
3483 content = b("Watch out! \0 Did you see it?")
3484 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3485 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3486 sig = sign(priv_key, content, "sha1")
3487 verify(good_cert, sig, content, "sha1")
3488
3489
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003490class EllipticCurveTests(TestCase):
3491 """
3492 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3493 :py:obj:`get_elliptic_curves`.
3494 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003495
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003496 def test_set(self):
3497 """
3498 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3499 """
3500 self.assertIsInstance(get_elliptic_curves(), set)
3501
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003502 def test_some_curves(self):
3503 """
3504 If :py:mod:`cryptography` has elliptic curve support then the set
3505 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3506 it.
3507
3508 There could be an OpenSSL that violates this assumption. If so, this
3509 test will fail and we'll find out.
3510 """
3511 curves = get_elliptic_curves()
3512 if lib.Cryptography_HAS_EC:
3513 self.assertTrue(curves)
3514 else:
3515 self.assertFalse(curves)
3516
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003517 def test_a_curve(self):
3518 """
3519 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3520 supported curve.
3521 """
3522 curves = get_elliptic_curves()
3523 if curves:
3524 curve = next(iter(curves))
3525 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3526 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003527 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003528
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003529 def test_not_a_curve(self):
3530 """
3531 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3532 with a name which does not identify a supported curve.
3533 """
3534 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003535 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003536
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003537 def test_repr(self):
3538 """
3539 The string representation of a curve object includes simply states the
3540 object is a curve and what its name is.
3541 """
3542 curves = get_elliptic_curves()
3543 if curves:
3544 curve = next(iter(curves))
3545 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3546
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003547 def test_to_EC_KEY(self):
3548 """
3549 The curve object can export a version of itself as an EC_KEY* via the
3550 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3551 """
3552 curves = get_elliptic_curves()
3553 if curves:
3554 curve = next(iter(curves))
3555 # It's not easy to assert anything about this object. However, see
3556 # leakcheck/crypto.py for a test that demonstrates it at least does
3557 # not leak memory.
3558 curve._to_EC_KEY()
3559
3560
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003561class EllipticCurveFactory(object):
3562 """
3563 A helper to get the names of two curves.
3564 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003565
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003566 def __init__(self):
3567 curves = iter(get_elliptic_curves())
3568 try:
3569 self.curve_name = next(curves).name
3570 self.another_curve_name = next(curves).name
3571 except StopIteration:
3572 self.curve_name = self.another_curve_name = None
3573
3574
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003575class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3576 """
3577 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3578 """
3579 curve_factory = EllipticCurveFactory()
3580
3581 if curve_factory.curve_name is None:
3582 skip = "There are no curves available there can be no curve objects."
3583
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003584 def anInstance(self):
3585 """
3586 Get the curve object for an arbitrary curve supported by the system.
3587 """
3588 return get_elliptic_curve(self.curve_factory.curve_name)
3589
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003590 def anotherInstance(self):
3591 """
3592 Get the curve object for an arbitrary curve supported by the system -
3593 but not the one returned by C{anInstance}.
3594 """
3595 return get_elliptic_curve(self.curve_factory.another_curve_name)
3596
3597
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003598class EllipticCurveHashTests(TestCase):
3599 """
3600 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3601 as an item in a :py:type:`dict` or :py:type:`set`).
3602 """
3603 curve_factory = EllipticCurveFactory()
3604
3605 if curve_factory.curve_name is None:
3606 skip = "There are no curves available there can be no curve objects."
3607
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003608 def test_contains(self):
3609 """
3610 The ``in`` operator reports that a :py:type:`set` containing a curve
3611 does contain that curve.
3612 """
3613 curve = get_elliptic_curve(self.curve_factory.curve_name)
3614 curves = set([curve])
3615 self.assertIn(curve, curves)
3616
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003617 def test_does_not_contain(self):
3618 """
3619 The ``in`` operator reports that a :py:type:`set` not containing a
3620 curve does not contain that curve.
3621 """
3622 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003623 curves = set([
3624 get_elliptic_curve(self.curve_factory.another_curve_name)
3625 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003626 self.assertNotIn(curve, curves)
3627
3628
Rick Dean5b7b6372009-04-01 11:34:06 -05003629if __name__ == '__main__':
3630 main()