blob: 0f1c867f5ade7f7ae353be3eb4076baa053a9d67 [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
Paul Kehrer72d968b2016-07-29 15:31:04 +080021from cryptography.hazmat.backends.openssl.backend import backend
22from cryptography.hazmat.primitives import serialization
23from cryptography.hazmat.primitives.asymmetric import rsa
24
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050025from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050026from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
Alex Gaynor31287502015-09-05 16:11:27 -040027from OpenSSL.crypto import (
Dan Sully44e767a2016-06-04 18:05:27 -070028 X509Store,
29 X509StoreFlags,
30 X509StoreType,
31 X509StoreContext,
32 X509StoreContextError
Alex Gaynor31287502015-09-05 16:11:27 -040033)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070034from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -050035from OpenSSL.crypto import X509Extension, X509ExtensionType
Rick Dean5b7b6372009-04-01 11:34:06 -050036from OpenSSL.crypto import load_certificate, load_privatekey
Cory Benfield6492f7c2015-10-27 16:57:58 +090037from OpenSSL.crypto import load_publickey, dump_publickey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040038from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040039from OpenSSL.crypto import dump_certificate, load_certificate_request
40from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040041from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Jean-Paul Calderone9178ee62010-01-25 17:55:30 -050042from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000043from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040044from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040045from OpenSSL.crypto import (
46 sign, verify, get_elliptic_curve, get_elliptic_curves)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020047from OpenSSL._util import native, lib
48
49from .util import (
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040050 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
51)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040052
Alex Gaynoraceb3e22015-09-05 12:00:22 -040053
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040054def normalize_certificate_pem(pem):
55 return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
56
57
58def normalize_privatekey_pem(pem):
59 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
60
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040061
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050062GOOD_CIPHER = "blowfish"
63BAD_CIPHER = "zippers"
64
Anthony Alba2ce737f2015-12-04 11:04:56 +080065GOOD_DIGEST = "SHA1"
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050066BAD_DIGEST = "monkeys"
67
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040068root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050069MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
70BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
71ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
72NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
73MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
74ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
75urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
762xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
771dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
78FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
79VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
80BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
81b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
82AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
83hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
84w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
85-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040086""")
Rick Dean94e46fd2009-07-18 14:51:24 -050087
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040088root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050089MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
90jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
913claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
92AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
93yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
946JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
95BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
96u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
97PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
98I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
99ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
1006AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
101cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
102-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400103""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500104
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700105intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
106MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
107WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
108DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
109ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
110dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
111MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
112AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
113FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
11421H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
115AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
116QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1179n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1189mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
119-----END CERTIFICATE-----
120""")
121
122intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
123MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
124ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
125qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
126AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
127rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
128147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
129+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
130wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
131sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
13252vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
133DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
134/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
135NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
136-----END RSA PRIVATE KEY-----
137""")
138
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400139server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500140MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
141BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
142VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
143NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
144gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
145lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
146b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
147lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
148gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
149dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1502mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
151uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
152-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400153""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500154
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400155server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500156MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
157U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
158SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
159AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
160j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
161j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
162Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
163msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
164FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1654e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1661sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
167NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
168r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
169-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400170"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500171
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700172intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
173MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
174ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
175CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
176biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
177BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
178CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
179biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
180iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
181+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
182biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
183UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1843bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
185x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
186-----END CERTIFICATE-----
187""")
188
189intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
190MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
191SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1928Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
193AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1945ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
195d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
196z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
197dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
198EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
199X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
2009UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
201ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
202nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
203-----END RSA PRIVATE KEY-----
204""")
205
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400206client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500207MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
208BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
209VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
210ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
211MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
212rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
213iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
214oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2150fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
216Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2179Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
218PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
219-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400220""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500221
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400222client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500223MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
224btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
225eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
226AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
227zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
228h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
229V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
230TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
231dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
232D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
233si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
234JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
235f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
236-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400237"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400238
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400239cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400240MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
241BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
242ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
243NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
244MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
245ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
246urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2472xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2481dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
249FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
250VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
251BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
252b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
253AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
254hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
255w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
256-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400257""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400258
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400259cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
260-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400261MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
262jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2633claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
264AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
265yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2666JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
267BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
268u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
269PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
270I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
271ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2726AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
273cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
274-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400275"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400276
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400277cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
278MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
279EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
280ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
281BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
282E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
283xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
284gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
285Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
286oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
287-----END CERTIFICATE REQUEST-----
288""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500289
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400290encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400291Proc-Type: 4,ENCRYPTED
292DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400293
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400294SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
295a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2968+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
297mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
298+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
299fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
300tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
301rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
302gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
303o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
3047SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
305MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
30611n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
307-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400308""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400309
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400310encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400311
Cory Benfield6492f7c2015-10-27 16:57:58 +0900312
313cleartextPublicKeyPEM = b("""-----BEGIN PUBLIC KEY-----
314MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
315gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
31690qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
317ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
318XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
3198Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
320ywIDAQAB
321-----END PUBLIC KEY-----
322""")
323
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400324# Some PKCS#7 stuff. Generated with the openssl command line:
325#
326# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
327#
328# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400329pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400330-----BEGIN PKCS7-----
331MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
332BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
333A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
334MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
335cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
336A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
337HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
338SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
339zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
340LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
341A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
34265w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
343Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
344Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
345bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
346VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
347/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
348Ho4EzbYCOaEAMQA=
349-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400350""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400351
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700352pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700353MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
354BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
355A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
356MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
357cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
358A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
359HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
360SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
361zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
362LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
363A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
36465w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
365Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
366Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
367bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
368VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
369/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
370Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700371""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700372
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400373crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500374-----BEGIN X509 CRL-----
375MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
376SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
377D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
378MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
379MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3804dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3810yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
382vrzEeLDRiiPl92dyyWmu
383-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400384""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400385
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400386crlDataUnsupportedExtension = b("""\
387-----BEGIN X509 CRL-----
388MIIGRzCCBS8CAQIwDQYJKoZIhvcNAQELBQAwJzELMAkGA1UEBhMCVVMxGDAWBgNV
389BAMMD2NyeXB0b2dyYXBoeS5pbxgPMjAxNTAxMDEwMDAwMDBaGA8yMDE2MDEwMTAw
390MDAwMFowggTOMBQCAQAYDzIwMTUwMTAxMDAwMDAwWjByAgEBGA8yMDE1MDEwMTAw
391MDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAn
392MQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQD
393CgEAMHICAQIYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAw
394MDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlw
395dG9ncmFwaHkuaW8wCgYDVR0VBAMKAQEwcgIBAxgPMjAxNTAxMDEwMDAwMDBaMFww
396GAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTArpCkwJzELMAkGA1UE
397BhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNVHRUEAwoBAjByAgEE
398GA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQG
399A1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5
400LmlvMAoGA1UdFQQDCgEDMHICAQUYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQR
401GA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgw
402FgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQQwcgIBBhgPMjAxNTAx
403MDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTAr
404pCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNV
405HRUEAwoBBTByAgEHGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAx
406MDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwP
407Y3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEGMHICAQgYDzIwMTUwMTAxMDAwMDAw
408WjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJ
409BgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQgw
410cgIBCRgPMjAxNTAxMDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAw
411WjA0BgNVHR0ELTArpCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dy
412YXBoeS5pbzAKBgNVHRUEAwoBCTByAgEKGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNV
413HRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJV
414UzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEKMC4CAQsYDzIw
415MTUwMTAxMDAwMDAwWjAYMAoGA1UdFQQDCgEBMAoGAyoDBAQDCgEAMA0GCSqGSIb3
416DQEBCwUAA4IBAQBTaloHlPaCZzYee8LxkWej5meiqxQVNWFoVdjesroa+f1FRrH+
417drRU60Nq97KCKf7f9GNN/J3ZIlQmYhmuDqh12f+XLpotoj1ZRfBz2hjFCkJlv+2c
418oWWGNHgA70ndFoVtcmX088SYpX8E3ARATivS4q2h9WlwV6rO93mhg3HGIe3JpcK4
4197BcW6Poi/ut/zsDOkVbI00SqaujRpdmdCTht82MH3ztjyDkI9KYaD/YEweKSrWOz
420SdEILd164bfBeLuplVI+xpmTEMVNpXBlSXl7+xIw9Vk7p7Q1Pa3k/SvhOldYCm6y
421C1xAg/AAq6w78yzYt18j5Mj0s6eeHi1YpHKw
422-----END X509 CRL-----
423""")
424
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400425
426# A broken RSA private key which can be used to test the error path through
427# PKey.check.
428inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
429MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
4305kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
431OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
432zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
433nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
434HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
435oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
436-----END RSA PRIVATE KEY-----
437""")
438
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400439# certificate with NULL bytes in subjectAltName and common name
440
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400441nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400442MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
443DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
444eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
445RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
446ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
447NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
448DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
449ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
450ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
451hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
452BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
453pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
454vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
455KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
456oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
45708LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
458HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
459BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
460Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
461bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
462AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
463i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
464HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
465kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
466VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
467RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
468-----END CERTIFICATE-----""")
469
Colleen Murphye09399b2016-03-01 17:40:49 -0800470large_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
471MIIJYgIBAAKCAg4AtRua8eIeevRfsj+fkcHr1vmse7Kgb+oX1ssJAvCb1R7JQMnH
472hNDjDP6b3vEkZuPUzlDHymP+cNkXvvi4wJ4miVbO3+SeU4Sh+jmsHeHzGIXat9xW
4739PFtuPM5FQq8zvkY8aDeRYmYwN9JKu4/neMBCBqostYlTEWg+bSytO/qWnyHTHKh
474g0GfaDdqUQPsGQw+J0MgaYIjQOCVASHAPlzbDQLCtuOb587rwTLkZA2GwoHB/LyJ
475BwT0HHgBaiObE12Vs6wi2en0Uu11CiwEuK1KIBcZ2XbE6eApaZa6VH9ysEmUxPt7
476TqyZ4E2oMIYaLPNRxuvozdwTlj1svI1k1FrkaXGc5MTjbgigPMKjIb0T7b/4GNzt
477DhP1LvAeUMnrEi3hJJrcJPXHPqS8/RiytR9xQQW6Sdh4LaA3f9MQm3WSevWage3G
478P8YcCLssOVKsArDjuA52NF5LmYuAeUzXprm4ITDi2oO+0iFBpFW6VPEK4A9vO0Yk
479M/6Wt6tG8zyWhaSH1zFUTwfQ9Yvjyt5w1lrUaAJuoTpwbMVZaDJaEhjOaXU0dyPQ
480jOsePDOQcU6dkeTWsQ3LsHPEEug/X6819TLG5mb3V7bvV9nPFBfTJSCEG794kr90
481XgZfIN71FrdByxLerlbuJI21pPs/nZi9SXi9jAWeiS45/azUxMsyYgJArui+gjq7
482sV1pWiBm6/orAgMBAAECggINQp5L6Yu+oIXBqcSjgq8tfF9M5hd30pLuf/EheHZf
483LA7uAqn2fVGFI2OInIJhXIOT5OxsAXO0xXfltzawZxIFpOFMqajj4F7aYjvSpw9V
484J4EdSiJ/zgv8y1qUdbwEZbHVThRZjoSlrtSzilonBoHZAE0mHtqMz7iRFSk1zz6t
485GunRrvo/lROPentf3TsvHquVNUYI5yaapyO1S7xJhecMIIYSb8nbsHI54FBDGNas
4866mFmpPwI/47/6HTwOEWupnn3NicsjrHzUInOUpaMig4cRR+aP5bjqg/ty8xI8AoN
487evEmCytiWTc+Rvbp1ieN+1jpjN18PjUk80/W7qioHUDt4ieLic8uxWH2VD9SCEnX
488Mpi9tA/FqoZ+2A/3m1OfrY6jiZVE2g+asi9lCK7QVWL39eK82H4rPvtp0/dyo1/i
489ZZz68TXg+m8IgEZcp88hngbkuoTTzpGE73QuPKhGA1uMIimDdqPPB5WP76q+03Oi
490IRR5DfZnqPERed49by0enJ7tKa/gFPZizOV8ALKr0Dp+vfAkxGDLPLBLd2A3//tw
491xg0Q/wltihHSBujv4nYlDXdc5oYyMYZ+Lhc/VuOghHfBq3tgEQ1ECM/ofqXEIdy7
492nVcpZn3Eeq8Jl5CrqxE1ee3NxlzsJHn99yGQpr7mOhW/psJF3XNz80Meg3L4m1T8
493sMBK0GbaassuJhdzb5whAoIBBw48sx1b1WR4XxQc5O/HjHva+l16i2pjUnOUTcDF
494RWmSbIhBm2QQ2rVhO8+fak0tkl6ZnMWW4i0U/X5LOEBbC7+IS8bO3j3Revi+Vw5x
495j96LMlIe9XEub5i/saEWgiz7maCvfzLFU08e1OpT4qPDpP293V400ubA6R7WQTCv
496pBkskGwHeu0l/TuKkVqBFFUTu7KEbps8Gjg7MkJaFriAOv1zis/umK8pVS3ZAM6e
4978w5jfpRccn8Xzta2fRwTB5kCmfxdDsY0oYGxPLRAbW72bORoLGuyyPp/ojeGwoik
498JX9RttErc6FjyZtks370Pa8UL5QskyhMbDhrZW2jFD+RXYM1BrvmZRjbAoIBBwy4
499iFJpuDfytJfz1MWtaL5DqEL/kmiZYAXl6hifNhGu5GAipVIIGsDqEYW4i+VC15aa
5007kOCwz/I5zsB3vSDW96IRs4wXtqEZSibc2W/bqfVi+xcvPPl1ZhQ2EAwa4D/x035
501kyf20ffWOU+1yf2cnijzqs3IzlveUm+meLw5s3Rc+iG7DPWWeCoe1hVwANI1euNc
502pqKwKY905yFyjOje2OgiEU2kS4YME4zGeBys8yo7E42hNnN2EPK6xkkUqzdudLLQ
5038OUlKRTc8AbIf3XG1rpA4VUpTv3hhxGGwCRy6If8zgZQsNYchgNztRGk72Gcb8Dm
504vFSEN3ZtwxU64G3YZzntdcr2WPzxAoIBBw30g6Fgdb/gmVnOpL0//T0ePNDKIMPs
505jVJLaRduhoZgB1Bb9qPUPX0SzRzLZtg1tkZSDjBDoHmOHJfhxUaXt+FLCPPbrE4t
506+nq9n/nBaMM779w9ClqhqLOyGrwKoxjSmhi+TVEHyIxCbXMvPHVHfX9WzxjbcGrN
507ZvRaEVZWo+QlIX8yqdSwqxLk1WtAIRzvlcj7NKum8xBxPed6BNFep/PtgIAmoLT5
508L8wb7EWb2iUdc2KbZ4OaY51lDScqpATgXu3WjXfM+Q52G0mX6Wyd0cjlL711Zrjb
509yLbiueZT94lgIHHRRKtKc8CEqcjkQV5OzABS3P/gQSfgZXBdLKjOpTnKDUq7IBeH
510AoIBBweAOEIAPLQg1QRUrr3xRrYKRwlakgZDii9wJt1l5AgBTICzbTA1vzDJ1JM5
511AqSpCV6w9JWyYVcXK+HLdKBRZLaPPNEQDJ5lOxD6uMziWGl2rg8tj+1xNMWfxiPz
512aTCjoe4EoBUMoTq2gwzRcM2usEQNikXVhnj9Wzaivsaeb4bJ3GRPW5DkrO6JSEtT
513w+gvyMqQM2Hy5k7E7BT46sXVwaj/jZxuqGnebRixXtnp0WixdRIqYWUr1UqLf6hQ
514G7WP2BgoxCMaCmNW8+HMD/xuxucEotoIhZ+GgJKBFoNnjl3BX+qxYdSe9RbL/5Tr
5154It6Jxtj8uETJXEbv9Cg6v1agWPS9YY8RLTBAoIBBwrU2AsAUts6h1LgGLKK3UWZ
516oLH5E+4o+7HqSGRcRodVeN9NBXIYdHHOLeEG6YNGJiJ3bFP5ZQEu9iDsyoFVKJ9O
517Mw/y6dKZuxOCZ+X8FopSROg3yWfdOpAm6cnQZp3WqLNX4n/Q6WvKojfyEiPphjwT
5180ymrUJELXLWJmjUyPoAk6HgC0Gs28ZnEXbyhx7CSbZNFyCU/PNUDZwto3GisIPD3
519le7YjqHugezmjMGlA0sDw5aCXjfbl74vowRFYMO6e3ItApfSRgNV86CDoX74WI/5
520AYU/QVM4wGt8XGT2KwDFJaxYGKsGDMWmXY04dS+WPuetCbouWUusyFwRb9SzFave
521vYeU7Ab/
522-----END RSA PRIVATE KEY-----""")
523
Paul Kehrer72d968b2016-07-29 15:31:04 +0800524ec_private_key_pem = b"""-----BEGIN PRIVATE KEY-----
525MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgYirTZSx+5O8Y6tlG
526cka6W6btJiocdrdolfcukSoTEk+hRANCAAQkvPNu7Pa1GcsWU4v7ptNfqCJVq8Cx
527zo0MUVPQgwJ3aJtNM1QMOQUayCrRwfklg+D/rFSUwEUqtZh7fJDiFqz3
528-----END PRIVATE KEY-----
529"""
530
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400531
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400532class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400533 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900534 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400535 """
536
537 def setUp(self):
538 """
539 Create a new private key and start a certificate request (for a test
540 method to finish in one way or another).
541 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800542 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400543 # Basic setup stuff to generate a certificate
544 self.pkey = PKey()
545 self.pkey.generate_key(TYPE_RSA, 384)
546 self.req = X509Req()
547 self.req.set_pubkey(self.pkey)
548 # Authority good you have.
549 self.req.get_subject().commonName = "Yoda root CA"
550 self.x509 = X509()
551 self.subject = self.x509.get_subject()
552 self.subject.commonName = self.req.get_subject().commonName
553 self.x509.set_issuer(self.subject)
554 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400555 now = datetime.now()
556 expire = datetime.now() + timedelta(days=100)
557 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
558 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400559
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800560 def tearDown(self):
561 """
562 Forget all of the pyOpenSSL objects so they can be garbage collected,
563 their memory released, and not interfere with the leak detection code.
564 """
565 self.pkey = self.req = self.x509 = self.subject = None
566 super(X509ExtTests, self).tearDown()
567
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400568 def test_str(self):
569 """
Alex Gaynor31287502015-09-05 16:11:27 -0400570 The string representation of :py:class:`X509Extension` instances as
571 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400572 """
573 # This isn't necessarily the best string representation. Perhaps it
574 # will be changed/improved in the future.
575 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400576 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400577 'CA:FALSE')
578
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400579 def test_type(self):
580 """
Alex Gaynor31287502015-09-05 16:11:27 -0400581 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
582 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400583 """
584 self.assertIdentical(X509Extension, X509ExtensionType)
585 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400586 X509Extension,
587 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400588
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500589 def test_construction(self):
590 """
Alex Gaynor31287502015-09-05 16:11:27 -0400591 :py:class:`X509Extension` accepts an extension type name, a critical
592 flag, and an extension value and returns an
593 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500594 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400595 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500596 self.assertTrue(
597 isinstance(basic, X509ExtensionType),
598 "%r is of type %r, should be %r" % (
599 basic, type(basic), X509ExtensionType))
600
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400601 comment = X509Extension(
602 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500603 self.assertTrue(
604 isinstance(comment, X509ExtensionType),
605 "%r is of type %r, should be %r" % (
606 comment, type(comment), X509ExtensionType))
607
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500608 def test_invalid_extension(self):
609 """
Alex Gaynor31287502015-09-05 16:11:27 -0400610 :py:class:`X509Extension` raises something if it is passed a bad
611 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500612 """
613 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400614 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500615 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400616 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500617
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500618 # Exercise a weird one (an extension which uses the r2i method). This
619 # exercises the codepath that requires a non-NULL ctx to be passed to
620 # X509V3_EXT_nconf. It can't work now because we provide no
621 # configuration database. It might be made to work in the future.
622 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400623 Error, X509Extension, b('proxyCertInfo'), True,
624 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500625
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500626 def test_get_critical(self):
627 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900628 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500629 extension's critical flag.
630 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400631 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500632 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400633 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500634 self.assertFalse(ext.get_critical())
635
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500636 def test_get_short_name(self):
637 """
Alex Gaynor31287502015-09-05 16:11:27 -0400638 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
639 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500640 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400641 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
642 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
643 ext = X509Extension(b('nsComment'), True, b('foo bar'))
644 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500645
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400646 def test_get_data(self):
647 """
Alex Gaynor31287502015-09-05 16:11:27 -0400648 :py:meth:`X509Extension.get_data` returns a string giving the data of
649 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400650 """
651 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
652 # Expect to get back the DER encoded form of CA:true.
653 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
654
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400655 def test_get_data_wrong_args(self):
656 """
Alex Gaynor31287502015-09-05 16:11:27 -0400657 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
658 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400659 """
660 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
661 self.assertRaises(TypeError, ext.get_data, None)
662 self.assertRaises(TypeError, ext.get_data, "foo")
663 self.assertRaises(TypeError, ext.get_data, 7)
664
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400665 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500666 """
Alex Gaynor31287502015-09-05 16:11:27 -0400667 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
668 provided for an extension which does not use it and is ignored in this
669 case.
Rick Dean47262da2009-07-08 16:17:17 -0500670 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400671 ext1 = X509Extension(
672 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400673 self.x509.add_extensions([ext1])
674 self.x509.sign(self.pkey, 'sha1')
675 # This is a little lame. Can we think of a better way?
676 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400677 self.assertTrue(b('X509v3 Basic Constraints:') in text)
678 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400679
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400680 def test_subject(self):
681 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900682 If an extension requires a subject, the :py:data:`subject` parameter to
683 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400684 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400685 ext3 = X509Extension(
686 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400687 self.x509.add_extensions([ext3])
688 self.x509.sign(self.pkey, 'sha1')
689 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400690 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400691
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400692 def test_missing_subject(self):
693 """
Alex Gaynor31287502015-09-05 16:11:27 -0400694 If an extension requires a subject and the :py:data:`subject` parameter
695 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400696 """
697 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400698 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400699
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400700 def test_invalid_subject(self):
701 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900702 If the :py:data:`subject` parameter is given a value which is not an
703 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400704 """
705 for badObj in [True, object(), "hello", [], self]:
706 self.assertRaises(
707 TypeError,
708 X509Extension,
709 'basicConstraints', False, 'CA:TRUE', subject=badObj)
710
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400711 def test_unused_issuer(self):
712 """
Alex Gaynor31287502015-09-05 16:11:27 -0400713 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
714 provided for an extension which does not use it and is ignored in this
715 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400716 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400717 ext1 = X509Extension(
718 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400719 self.x509.add_extensions([ext1])
720 self.x509.sign(self.pkey, 'sha1')
721 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400722 self.assertTrue(b('X509v3 Basic Constraints:') in text)
723 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400724
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400725 def test_issuer(self):
726 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800727 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900728 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400729 """
730 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400731 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400732 issuer=self.x509)
733 self.x509.add_extensions([ext2])
734 self.x509.sign(self.pkey, 'sha1')
735 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400736 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
737 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400738
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400739 def test_missing_issuer(self):
740 """
Alex Gaynor31287502015-09-05 16:11:27 -0400741 If an extension requires an issue and the :py:data:`issuer` parameter
742 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400743 """
744 self.assertRaises(
745 Error,
746 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400747 b('authorityKeyIdentifier'), False,
748 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400749
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400750 def test_invalid_issuer(self):
751 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900752 If the :py:data:`issuer` parameter is given a value which is not an
753 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400754 """
755 for badObj in [True, object(), "hello", [], self]:
756 self.assertRaises(
757 TypeError,
758 X509Extension,
759 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
760 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500761
762
Paul Kehrer72d968b2016-07-29 15:31:04 +0800763class TestPKey(object):
764 """
765 py.test-based tests for :class:`OpenSSL.crypto.PKey`.
766
767 If possible, add new tests here.
768 """
769
770 def test_convert_from_cryptography_private_key(self):
771 """
772 PKey.from_cryptography_key creates a proper private PKey.
773 """
774 key = serialization.load_pem_private_key(
775 intermediate_key_pem, None, backend
776 )
777 pkey = PKey.from_cryptography_key(key)
778
779 assert isinstance(pkey, PKey)
780 assert pkey.bits() == key.key_size
781 assert pkey._only_public is False
782 assert pkey._initialized is True
783
784 def test_convert_from_cryptography_public_key(self):
785 """
786 PKey.from_cryptography_key creates a proper public PKey.
787 """
788 key = serialization.load_pem_public_key(cleartextPublicKeyPEM, backend)
789 pkey = PKey.from_cryptography_key(key)
790
791 assert isinstance(pkey, PKey)
792 assert pkey.bits() == key.key_size
793 assert pkey._only_public is True
794 assert pkey._initialized is True
795
796 def test_convert_from_cryptography_unsupported_type(self):
797 """
798 PKey.from_cryptography_key raises TypeError with an unsupported type.
799 """
800 key = serialization.load_pem_private_key(
801 ec_private_key_pem, None, backend
802 )
803 with pytest.raises(TypeError):
804 PKey.from_cryptography_key(key)
805
806 def test_convert_public_pkey_to_cryptography_key(self):
807 """
808 PKey.to_cryptography_key creates a proper cryptography public key.
809 """
810 pkey = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
811 key = pkey.to_cryptography_key()
812
813 assert isinstance(key, rsa.RSAPublicKey)
814 assert pkey.bits() == key.key_size
815
816 def test_convert_private_pkey_to_cryptography_key(self):
817 """
818 PKey.to_cryptography_key creates a proper cryptography private key.
819 """
820 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
821 key = pkey.to_cryptography_key()
822
823 assert isinstance(key, rsa.RSAPrivateKey)
824 assert pkey.bits() == key.key_size
825
826
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400827class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500828 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900829 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500830 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400831
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400832 def test_type(self):
833 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900834 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
835 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400836 """
837 self.assertIdentical(PKey, PKeyType)
838 self.assertConsistentType(PKey, 'PKey')
839
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500840 def test_construction(self):
841 """
Alex Gaynor31287502015-09-05 16:11:27 -0400842 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
843 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500844 """
845 self.assertRaises(TypeError, PKey, None)
846 key = PKey()
847 self.assertTrue(
848 isinstance(key, PKeyType),
849 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
850
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500851 def test_pregeneration(self):
852 """
Alex Gaynor31287502015-09-05 16:11:27 -0400853 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
854 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
855 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500856 """
857 key = PKey()
858 self.assertEqual(key.type(), 0)
859 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400860 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500861
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500862 def test_failedGeneration(self):
863 """
Alex Gaynor31287502015-09-05 16:11:27 -0400864 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
865 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
866 the second giving the number of bits to generate. If an invalid type
867 is specified or generation fails, :py:exc:`Error` is raised. If an
868 invalid number of bits is specified, :py:exc:`ValueError` or
869 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500870 """
871 key = PKey()
872 self.assertRaises(TypeError, key.generate_key)
873 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
874 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
875 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500876
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500877 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
878 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500879
Alex Gaynor5bb2bd12016-07-03 10:48:32 -0400880 with pytest.raises(TypeError):
881 key.generate_key(TYPE_RSA, object())
882
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500883 # XXX RSA generation for small values of bits is fairly buggy in a wide
884 # range of OpenSSL versions. I need to figure out what the safe lower
885 # bound for a reasonable number of OpenSSL versions is and explicitly
886 # check for that in the wrapper. The failure behavior is typically an
887 # infinite loop inside OpenSSL.
888
889 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500890
891 # XXX DSA generation seems happy with any number of bits. The DSS
892 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
893 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500894 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500895 # So, it doesn't seem possible to make generate_key fail for
896 # TYPE_DSA with a bits argument which is at least an int.
897
898 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
899
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500900 def test_rsaGeneration(self):
901 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900902 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
903 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500904 """
905 bits = 128
906 key = PKey()
907 key.generate_key(TYPE_RSA, bits)
908 self.assertEqual(key.type(), TYPE_RSA)
909 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400910 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500911
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500912 def test_dsaGeneration(self):
913 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900914 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
915 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500916 """
917 # 512 is a magic number. The DSS (Digital Signature Standard)
918 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
919 # will silently promote any value below 512 to 512.
920 bits = 512
921 key = PKey()
922 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800923 # self.assertEqual(key.type(), TYPE_DSA)
924 # self.assertEqual(key.bits(), bits)
925 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500926
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500927 def test_regeneration(self):
928 """
Alex Gaynor31287502015-09-05 16:11:27 -0400929 :py:meth:`PKeyType.generate_key` can be called multiple times on the
930 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500931 """
932 key = PKey()
933 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400934 key.generate_key(type, bits)
935 self.assertEqual(key.type(), type)
936 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500937
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400938 def test_inconsistentKey(self):
939 """
Alex Gaynor31287502015-09-05 16:11:27 -0400940 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
941 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400942 """
943 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400944 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400945
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400946 def test_check_wrong_args(self):
947 """
Alex Gaynor31287502015-09-05 16:11:27 -0400948 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
949 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400950 """
951 self.assertRaises(TypeError, PKey().check, None)
952 self.assertRaises(TypeError, PKey().check, object())
953 self.assertRaises(TypeError, PKey().check, 1)
954
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400955 def test_check_public_key(self):
956 """
957 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
958 part of the key is available.
959 """
960 # A trick to get a public-only key
961 key = PKey()
962 key.generate_key(TYPE_RSA, 512)
963 cert = X509()
964 cert.set_pubkey(key)
965 pub = cert.get_pubkey()
966 self.assertRaises(TypeError, pub.check)
967
968
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400969class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500970 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900971 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500972 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400973
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500974 def _x509name(self, **attrs):
975 # XXX There's no other way to get a new X509Name yet.
976 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400977 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400978
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500979 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400980 def key(attr):
981 return attr[1]
982 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500983 for k, v in attrs:
984 setattr(name, k, v)
985 return name
986
Rick Deane15b1472009-07-09 15:53:42 -0500987 def test_type(self):
988 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900989 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500990 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400991 self.assertIdentical(X509Name, X509NameType)
992 self.assertEqual(X509NameType.__name__, 'X509Name')
993 self.assertTrue(isinstance(X509NameType, type))
994
Rick Deane15b1472009-07-09 15:53:42 -0500995 name = self._x509name()
996 self.assertTrue(
997 isinstance(name, X509NameType),
998 "%r is of type %r, should be %r" % (
999 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -05001000
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001001 def test_onlyStringAttributes(self):
1002 """
Alex Gaynor31287502015-09-05 16:11:27 -04001003 Attempting to set a non-:py:data:`str` attribute name on an
1004 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
1005 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001006 """
1007 name = self._x509name()
1008 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -04001009 # rejected. Sorry, you're wrong. unicode is automatically converted
1010 # to str outside of the control of X509Name, so there's no way to
1011 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -08001012
Alex Gaynor31287502015-09-05 16:11:27 -04001013 # Also, this used to test str subclasses, but that test is less
1014 # relevant now that the implementation is in Python instead of C. Also
1015 # PyPy automatically converts str subclasses to str when they are
1016 # passed to setattr, so we can't test it on PyPy. Apparently CPython
1017 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001018 self.assertRaises(TypeError, setattr, name, None, "hello")
1019 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001020
1021 def test_setInvalidAttribute(self):
1022 """
Alex Gaynor31287502015-09-05 16:11:27 -04001023 Attempting to set any attribute name on an :py:class:`X509NameType`
1024 instance for which no corresponding NID is defined causes
1025 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001026 """
1027 name = self._x509name()
1028 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
1029
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001030 def test_attributes(self):
1031 """
Alex Gaynor31287502015-09-05 16:11:27 -04001032 :py:class:`X509NameType` instances have attributes for each standard
1033 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001034 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001035 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001036 name.commonName = "foo"
Alex Gaynor37726112016-07-04 09:51:32 -04001037 assert name.commonName == "foo"
1038 assert name.CN == "foo"
1039
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001040 name.CN = "baz"
Alex Gaynor37726112016-07-04 09:51:32 -04001041 assert name.commonName == "baz"
1042 assert name.CN == "baz"
1043
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001044 name.commonName = "bar"
Alex Gaynor37726112016-07-04 09:51:32 -04001045 assert name.commonName == "bar"
1046 assert name.CN == "bar"
1047
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001048 name.CN = "quux"
Alex Gaynor37726112016-07-04 09:51:32 -04001049 assert name.commonName == "quux"
1050 assert name.CN == "quux"
1051
1052 assert name.OU is None
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001053
Alex Gaynor7778e792016-07-03 23:38:48 -04001054 with pytest.raises(AttributeError):
1055 name.foobar
1056
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001057 def test_copy(self):
1058 """
Alex Gaynor31287502015-09-05 16:11:27 -04001059 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
1060 with all the same attributes as an existing :py:class:`X509NameType`
1061 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001062 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001063 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001064
1065 copy = X509Name(name)
1066 self.assertEqual(copy.commonName, "foo")
1067 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001068
1069 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001070 copy.commonName = "baz"
1071 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001072
1073 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001074 name.emailAddress = "quux@example.com"
1075 self.assertEqual(copy.emailAddress, "bar@example.com")
1076
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001077 def test_repr(self):
1078 """
Alex Gaynor31287502015-09-05 16:11:27 -04001079 :py:func:`repr` passed an :py:class:`X509NameType` instance should
1080 return a string containing a description of the type and the NIDs which
1081 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001082 """
1083 name = self._x509name(commonName="foo", emailAddress="bar")
1084 self.assertEqual(
1085 repr(name),
1086 "<X509Name object '/emailAddress=bar/CN=foo'>")
1087
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001088 def test_comparison(self):
1089 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001090 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001091 """
1092 def _equality(a, b, assertTrue, assertFalse):
1093 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
1094 assertFalse(a != b)
1095 assertTrue(b == a)
1096 assertFalse(b != a)
1097
1098 def assertEqual(a, b):
1099 _equality(a, b, self.assertTrue, self.assertFalse)
1100
1101 # Instances compare equal to themselves.
1102 name = self._x509name()
1103 assertEqual(name, name)
1104
1105 # Empty instances should compare equal to each other.
1106 assertEqual(self._x509name(), self._x509name())
1107
1108 # Instances with equal NIDs should compare equal to each other.
1109 assertEqual(self._x509name(commonName="foo"),
1110 self._x509name(commonName="foo"))
1111
1112 # Instance with equal NIDs set using different aliases should compare
1113 # equal to each other.
1114 assertEqual(self._x509name(commonName="foo"),
1115 self._x509name(CN="foo"))
1116
1117 # Instances with more than one NID with the same values should compare
1118 # equal to each other.
1119 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
1120 self._x509name(commonName="foo", OU="bar"))
1121
1122 def assertNotEqual(a, b):
1123 _equality(a, b, self.assertFalse, self.assertTrue)
1124
1125 # Instances with different values for the same NID should not compare
1126 # equal to each other.
1127 assertNotEqual(self._x509name(CN="foo"),
1128 self._x509name(CN="bar"))
1129
1130 # Instances with different NIDs should not compare equal to each other.
1131 assertNotEqual(self._x509name(CN="foo"),
1132 self._x509name(OU="foo"))
1133
Alex Gaynor7778e792016-07-03 23:38:48 -04001134 assertNotEqual(self._x509name(), object())
1135
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001136 def _inequality(a, b, assertTrue, assertFalse):
1137 assertTrue(a < b)
1138 assertTrue(a <= b)
1139 assertTrue(b > a)
1140 assertTrue(b >= a)
1141 assertFalse(a > b)
1142 assertFalse(a >= b)
1143 assertFalse(b < a)
1144 assertFalse(b <= a)
1145
1146 def assertLessThan(a, b):
1147 _inequality(a, b, self.assertTrue, self.assertFalse)
1148
1149 # An X509Name with a NID with a value which sorts less than the value
1150 # of the same NID on another X509Name compares less than the other
1151 # X509Name.
1152 assertLessThan(self._x509name(CN="abc"),
1153 self._x509name(CN="def"))
1154
1155 def assertGreaterThan(a, b):
1156 _inequality(a, b, self.assertFalse, self.assertTrue)
1157
1158 # An X509Name with a NID with a value which sorts greater than the
1159 # value of the same NID on another X509Name compares greater than the
1160 # other X509Name.
1161 assertGreaterThan(self._x509name(CN="def"),
1162 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001163
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001164 def test_hash(self):
1165 """
Alex Gaynor31287502015-09-05 16:11:27 -04001166 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1167 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001168 """
1169 a = self._x509name(CN="foo")
1170 b = self._x509name(CN="foo")
1171 self.assertEqual(a.hash(), b.hash())
1172 a.CN = "bar"
1173 self.assertNotEqual(a.hash(), b.hash())
1174
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001175 def test_der(self):
1176 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001177 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001178 """
1179 a = self._x509name(CN="foo", C="US")
1180 self.assertEqual(
1181 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001182 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001183 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001184
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001185 def test_get_components(self):
1186 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001187 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1188 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001189 giving the NIDs and associated values which make up the name.
1190 """
1191 a = self._x509name()
1192 self.assertEqual(a.get_components(), [])
1193 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001194 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001195 a.organizationalUnitName = "bar"
1196 self.assertEqual(
1197 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001198 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001199
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001200 def test_load_nul_byte_attribute(self):
1201 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001202 An :py:class:`OpenSSL.crypto.X509Name` from an
1203 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001204 NUL byte in the value of one of its attributes.
1205 """
1206 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1207 subject = cert.get_subject()
1208 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001209 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001210
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001211 def test_setAttributeFailure(self):
1212 """
1213 If the value of an attribute cannot be set for some reason then
1214 :py:class:`OpenSSL.crypto.Error` is raised.
1215 """
1216 name = self._x509name()
1217 # This value is too long
1218 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1219
1220
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001221class _PKeyInteractionTestsMixin:
1222 """
1223 Tests which involve another thing and a PKey.
1224 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001225
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001226 def signable(self):
1227 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001228 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1229 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001230 """
1231 raise NotImplementedError()
1232
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001233 def test_signWithUngenerated(self):
1234 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001235 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1236 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001237 """
1238 request = self.signable()
1239 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001240 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001241
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001242 def test_signWithPublicKey(self):
1243 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001244 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1245 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001246 """
1247 request = self.signable()
1248 key = PKey()
1249 key.generate_key(TYPE_RSA, 512)
1250 request.set_pubkey(key)
1251 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001252 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001253
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001254 def test_signWithUnknownDigest(self):
1255 """
Alex Gaynor31287502015-09-05 16:11:27 -04001256 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1257 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001258 """
1259 request = self.signable()
1260 key = PKey()
1261 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001262 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001263
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001264 def test_sign(self):
1265 """
Alex Gaynor31287502015-09-05 16:11:27 -04001266 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1267 valid digest function. :py:meth:`X509Req.verify` can be used to check
1268 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001269 """
1270 request = self.signable()
1271 key = PKey()
1272 key.generate_key(TYPE_RSA, 512)
1273 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001274 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001275 # If the type has a verify method, cover that too.
1276 if getattr(request, 'verify', None) is not None:
1277 pub = request.get_pubkey()
1278 self.assertTrue(request.verify(pub))
1279 # Make another key that won't verify.
1280 key = PKey()
1281 key.generate_key(TYPE_RSA, 512)
1282 self.assertRaises(Error, request.verify, key)
1283
1284
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001285class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001286 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001287 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001288 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001289
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001290 def signable(self):
1291 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001292 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001293 """
1294 return X509Req()
1295
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001296 def test_type(self):
1297 """
Alex Gaynor31287502015-09-05 16:11:27 -04001298 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1299 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001300 """
1301 self.assertIdentical(X509Req, X509ReqType)
1302 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001303
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001304 def test_construction(self):
1305 """
Alex Gaynor31287502015-09-05 16:11:27 -04001306 :py:obj:`X509Req` takes no arguments and returns an
1307 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001308 """
1309 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001310 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001311
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001312 def test_version(self):
1313 """
Alex Gaynor31287502015-09-05 16:11:27 -04001314 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1315 certificate request. :py:obj:`X509ReqType.get_version` returns the
1316 X.509 version of the certificate request. The initial value of the
1317 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001318 """
1319 request = X509Req()
1320 self.assertEqual(request.get_version(), 0)
1321 request.set_version(1)
1322 self.assertEqual(request.get_version(), 1)
1323 request.set_version(3)
1324 self.assertEqual(request.get_version(), 3)
1325
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001326 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001327 """
Alex Gaynor31287502015-09-05 16:11:27 -04001328 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1329 with the wrong number of arguments or with a non-:py:obj:`int`
1330 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1331 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001332 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001333 request = X509Req()
1334 self.assertRaises(TypeError, request.set_version)
1335 self.assertRaises(TypeError, request.set_version, "foo")
1336 self.assertRaises(TypeError, request.set_version, 1, 2)
1337 self.assertRaises(TypeError, request.get_version, None)
1338
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001339 def test_get_subject(self):
1340 """
Alex Gaynor31287502015-09-05 16:11:27 -04001341 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1342 subject of the request and which is valid even after the request object
1343 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001344 """
1345 request = X509Req()
1346 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001347 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001348 subject.commonName = "foo"
1349 self.assertEqual(request.get_subject().commonName, "foo")
1350 del request
1351 subject.commonName = "bar"
1352 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001353
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001354 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001355 """
Alex Gaynor31287502015-09-05 16:11:27 -04001356 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1357 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001358 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001359 request = X509Req()
1360 self.assertRaises(TypeError, request.get_subject, None)
1361
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001362 def test_add_extensions(self):
1363 """
Alex Gaynor31287502015-09-05 16:11:27 -04001364 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1365 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001366 """
1367 request = X509Req()
1368 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001369 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001370 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001371 self.assertEqual(len(exts), 1)
1372 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1373 self.assertEqual(exts[0].get_critical(), 1)
1374 self.assertEqual(exts[0].get_data(), b('0\x00'))
1375
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001376 def test_get_extensions(self):
1377 """
1378 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1379 extensions added to this X509 request.
1380 """
1381 request = X509Req()
1382 exts = request.get_extensions()
1383 self.assertEqual(exts, [])
1384 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001385 X509Extension(b('basicConstraints'), True, b('CA:true')),
1386 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001387 exts = request.get_extensions()
1388 self.assertEqual(len(exts), 2)
1389 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1390 self.assertEqual(exts[0].get_critical(), 1)
1391 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1392 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1393 self.assertEqual(exts[1].get_critical(), 0)
1394 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001395
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001396 def test_add_extensions_wrong_args(self):
1397 """
Alex Gaynor31287502015-09-05 16:11:27 -04001398 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1399 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1400 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1401 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001402 """
1403 request = X509Req()
1404 self.assertRaises(TypeError, request.add_extensions)
1405 self.assertRaises(TypeError, request.add_extensions, object())
1406 self.assertRaises(ValueError, request.add_extensions, [object()])
1407 self.assertRaises(TypeError, request.add_extensions, [], None)
1408
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001409 def test_verify_wrong_args(self):
1410 """
1411 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1412 arguments or more than one argument or if passed anything other than a
1413 :py:obj:`PKey` instance as its single argument.
1414 """
1415 request = X509Req()
1416 self.assertRaises(TypeError, request.verify)
1417 self.assertRaises(TypeError, request.verify, object())
1418 self.assertRaises(TypeError, request.verify, PKey(), object())
1419
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001420 def test_verify_uninitialized_key(self):
1421 """
Alex Gaynor31287502015-09-05 16:11:27 -04001422 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1423 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001424 """
1425 request = X509Req()
1426 pkey = PKey()
1427 self.assertRaises(Error, request.verify, pkey)
1428
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001429 def test_verify_wrong_key(self):
1430 """
Alex Gaynor31287502015-09-05 16:11:27 -04001431 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1432 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1433 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001434 """
1435 request = X509Req()
1436 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001437 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001438 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1439 self.assertRaises(Error, request.verify, another_pkey)
1440
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001441 def test_verify_success(self):
1442 """
1443 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001444 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1445 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001446 """
1447 request = X509Req()
1448 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001449 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001450 self.assertEqual(True, request.verify(pkey))
1451
1452
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001453class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001454 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001455 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001456 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001457 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001458
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001459 extpem = """
1460-----BEGIN CERTIFICATE-----
1461MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1462BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1463eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1464MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1465aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1466hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1467Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1468zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1469hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1470TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
147103HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1472MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1473b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1474MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1475uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1476WpOdIpB8KksUTCzV591Nr1wd
1477-----END CERTIFICATE-----
1478 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001479
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001480 def signable(self):
1481 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001482 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001483 """
1484 return X509()
1485
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001486 def test_type(self):
1487 """
Alex Gaynor31287502015-09-05 16:11:27 -04001488 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1489 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001490 """
1491 self.assertIdentical(X509, X509Type)
1492 self.assertConsistentType(X509, 'X509')
1493
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001494 def test_construction(self):
1495 """
Alex Gaynor31287502015-09-05 16:11:27 -04001496 :py:obj:`X509` takes no arguments and returns an instance of
1497 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001498 """
1499 certificate = X509()
1500 self.assertTrue(
1501 isinstance(certificate, X509Type),
1502 "%r is of type %r, should be %r" % (certificate,
1503 type(certificate),
1504 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001505 self.assertEqual(type(X509Type).__name__, 'type')
1506 self.assertEqual(type(certificate).__name__, 'X509')
1507 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001508 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001509
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001510 def test_get_version_wrong_args(self):
1511 """
Alex Gaynor31287502015-09-05 16:11:27 -04001512 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1513 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001514 """
1515 cert = X509()
1516 self.assertRaises(TypeError, cert.get_version, None)
1517
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001518 def test_set_version_wrong_args(self):
1519 """
Alex Gaynor31287502015-09-05 16:11:27 -04001520 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1521 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001522 """
1523 cert = X509()
1524 self.assertRaises(TypeError, cert.set_version)
1525 self.assertRaises(TypeError, cert.set_version, None)
1526 self.assertRaises(TypeError, cert.set_version, 1, None)
1527
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001528 def test_version(self):
1529 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001530 :py:obj:`X509.set_version` sets the certificate version number.
1531 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001532 """
1533 cert = X509()
1534 cert.set_version(1234)
1535 self.assertEquals(cert.get_version(), 1234)
1536
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001537 def test_get_serial_number_wrong_args(self):
1538 """
Alex Gaynor31287502015-09-05 16:11:27 -04001539 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1540 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001541 """
1542 cert = X509()
1543 self.assertRaises(TypeError, cert.get_serial_number, None)
1544
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001545 def test_serial_number(self):
1546 """
Alex Gaynor31287502015-09-05 16:11:27 -04001547 The serial number of an :py:obj:`X509Type` can be retrieved and
1548 modified with :py:obj:`X509Type.get_serial_number` and
1549 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001550 """
1551 certificate = X509()
1552 self.assertRaises(TypeError, certificate.set_serial_number)
1553 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1554 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1555 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1556 self.assertEqual(certificate.get_serial_number(), 0)
1557 certificate.set_serial_number(1)
1558 self.assertEqual(certificate.get_serial_number(), 1)
1559 certificate.set_serial_number(2 ** 32 + 1)
1560 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1561 certificate.set_serial_number(2 ** 64 + 1)
1562 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001563 certificate.set_serial_number(2 ** 128 + 1)
1564 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1565
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001566 def _setBoundTest(self, which):
1567 """
Alex Gaynor31287502015-09-05 16:11:27 -04001568 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1569 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1570 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001571 """
1572 certificate = X509()
1573 set = getattr(certificate, 'set_not' + which)
1574 get = getattr(certificate, 'get_not' + which)
1575
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001576 # Starts with no value.
1577 self.assertEqual(get(), None)
1578
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001579 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001580 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001581 set(when)
1582 self.assertEqual(get(), when)
1583
1584 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001585 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001586 set(when)
1587 self.assertEqual(get(), when)
1588
1589 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001590 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001591 set(when)
1592 self.assertEqual(get(), when)
1593
1594 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001595 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001596
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001597 # The wrong number of arguments results in a TypeError.
1598 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001599 with pytest.raises(TypeError):
1600 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001601 self.assertRaises(TypeError, get, b("foo bar"))
1602
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001603 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001604
1605 def test_set_notBefore(self):
1606 """
Alex Gaynor31287502015-09-05 16:11:27 -04001607 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1608 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1609 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001610 """
1611 self._setBoundTest("Before")
1612
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001613 def test_set_notAfter(self):
1614 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001615 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001616 GENERALIZEDTIME and sets the end of the certificate's validity period
1617 to it.
1618 """
1619 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001620
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001621 def test_get_notBefore(self):
1622 """
Alex Gaynor31287502015-09-05 16:11:27 -04001623 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1624 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001625 internally.
1626 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001627 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001628 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001629
Rick Dean38a05c82009-07-18 01:41:30 -05001630 def test_get_notAfter(self):
1631 """
Alex Gaynor31287502015-09-05 16:11:27 -04001632 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1633 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001634 internally.
1635 """
1636 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001637 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001638
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001639 def test_gmtime_adj_notBefore_wrong_args(self):
1640 """
Alex Gaynor31287502015-09-05 16:11:27 -04001641 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1642 called with the wrong number of arguments or a non-:py:obj:`int`
1643 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001644 """
1645 cert = X509()
1646 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1647 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1648 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1649
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001650 def test_gmtime_adj_notBefore(self):
1651 """
Alex Gaynor31287502015-09-05 16:11:27 -04001652 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1653 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001654 """
1655 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001656 not_before_min = (
1657 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1658 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001659 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001660 not_before = datetime.strptime(
1661 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1662 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001663 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1664 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001665
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001666 def test_gmtime_adj_notAfter_wrong_args(self):
1667 """
Alex Gaynor31287502015-09-05 16:11:27 -04001668 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1669 called with the wrong number of arguments or a non-:py:obj:`int`
1670 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001671 """
1672 cert = X509()
1673 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1674 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1675 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1676
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001677 def test_gmtime_adj_notAfter(self):
1678 """
Alex Gaynor31287502015-09-05 16:11:27 -04001679 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1680 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001681 """
1682 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001683 not_after_min = (
1684 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1685 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001686 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001687 not_after = datetime.strptime(
1688 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1689 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001690 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1691 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001692
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001693 def test_has_expired_wrong_args(self):
1694 """
Alex Gaynor31287502015-09-05 16:11:27 -04001695 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1696 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001697 """
1698 cert = X509()
1699 self.assertRaises(TypeError, cert.has_expired, None)
1700
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001701 def test_has_expired(self):
1702 """
Alex Gaynor31287502015-09-05 16:11:27 -04001703 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1704 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001705 """
1706 cert = X509()
1707 cert.gmtime_adj_notAfter(-1)
1708 self.assertTrue(cert.has_expired())
1709
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001710 def test_has_not_expired(self):
1711 """
Alex Gaynor31287502015-09-05 16:11:27 -04001712 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1713 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001714 """
1715 cert = X509()
1716 cert.gmtime_adj_notAfter(2)
1717 self.assertFalse(cert.has_expired())
1718
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001719 def test_root_has_not_expired(self):
1720 """
Alex Gaynor31287502015-09-05 16:11:27 -04001721 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1722 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001723 """
1724 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1725 self.assertFalse(cert.has_expired())
1726
Rick Dean38a05c82009-07-18 01:41:30 -05001727 def test_digest(self):
1728 """
Alex Gaynor31287502015-09-05 16:11:27 -04001729 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1730 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001731 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001732 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001733 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001734 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1735 # actually matters to the assertion (ie, another arbitrary, good
1736 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001737 # Digest verified with the command:
1738 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001739 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001740 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001741
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001742 def _extcert(self, pkey, extensions):
1743 cert = X509()
1744 cert.set_pubkey(pkey)
1745 cert.get_subject().commonName = "Unit Tests"
1746 cert.get_issuer().commonName = "Unit Tests"
1747 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1748 cert.set_notBefore(when)
1749 cert.set_notAfter(when)
1750
1751 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001752 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001753 return load_certificate(
1754 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1755
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001756 def test_extension_count(self):
1757 """
Alex Gaynor31287502015-09-05 16:11:27 -04001758 :py:obj:`X509.get_extension_count` returns the number of extensions
1759 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001760 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001761 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001762 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1763 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001764 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001765 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001766
1767 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001768 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001769 self.assertEqual(c.get_extension_count(), 0)
1770
1771 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001772 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001773 self.assertEqual(c.get_extension_count(), 1)
1774
1775 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001776 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001777 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001778
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001779 def test_get_extension(self):
1780 """
Alex Gaynor31287502015-09-05 16:11:27 -04001781 :py:obj:`X509.get_extension` takes an integer and returns an
1782 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001783 """
1784 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001785 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1786 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001787 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001788 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001789
1790 cert = self._extcert(pkey, [ca, key, subjectAltName])
1791
1792 ext = cert.get_extension(0)
1793 self.assertTrue(isinstance(ext, X509Extension))
1794 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001795 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001796
1797 ext = cert.get_extension(1)
1798 self.assertTrue(isinstance(ext, X509Extension))
1799 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001800 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001801
1802 ext = cert.get_extension(2)
1803 self.assertTrue(isinstance(ext, X509Extension))
1804 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001805 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001806
1807 self.assertRaises(IndexError, cert.get_extension, -1)
1808 self.assertRaises(IndexError, cert.get_extension, 4)
1809 self.assertRaises(TypeError, cert.get_extension, "hello")
1810
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001811 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001812 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001813 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001814 bytes and this value is reflected in the string representation of the
1815 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001816 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001817 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001818
1819 ext = cert.get_extension(3)
1820 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001821 self.assertEqual(
1822 b("DNS:altnull.python.org\x00example.com, "
1823 "email:null@python.org\x00user@example.org, "
1824 "URI:http://null.python.org\x00http://example.org, "
1825 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1826 b(str(ext)))
1827
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001828 def test_invalid_digest_algorithm(self):
1829 """
Alex Gaynor31287502015-09-05 16:11:27 -04001830 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1831 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001832 """
1833 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001834 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001835
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001836 def test_get_subject_wrong_args(self):
1837 """
Alex Gaynor31287502015-09-05 16:11:27 -04001838 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1839 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001840 """
1841 cert = X509()
1842 self.assertRaises(TypeError, cert.get_subject, None)
1843
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001844 def test_get_subject(self):
1845 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001846 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001847 """
1848 cert = load_certificate(FILETYPE_PEM, self.pemData)
1849 subj = cert.get_subject()
1850 self.assertTrue(isinstance(subj, X509Name))
1851 self.assertEquals(
1852 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001853 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1854 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001855
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001856 def test_set_subject_wrong_args(self):
1857 """
Alex Gaynor31287502015-09-05 16:11:27 -04001858 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1859 the wrong number of arguments or an argument not of type
1860 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001861 """
1862 cert = X509()
1863 self.assertRaises(TypeError, cert.set_subject)
1864 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001865 with pytest.raises(TypeError):
1866 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001867
1868 def test_set_subject(self):
1869 """
Alex Gaynor31287502015-09-05 16:11:27 -04001870 :py:obj:`X509.set_subject` changes the subject of the certificate to
1871 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001872 """
1873 cert = X509()
1874 name = cert.get_subject()
1875 name.C = 'AU'
1876 name.O = 'Unit Tests'
1877 cert.set_subject(name)
1878 self.assertEquals(
1879 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001880 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001881
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001882 def test_get_issuer_wrong_args(self):
1883 """
Alex Gaynor31287502015-09-05 16:11:27 -04001884 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1885 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001886 """
1887 cert = X509()
1888 self.assertRaises(TypeError, cert.get_issuer, None)
1889
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001890 def test_get_issuer(self):
1891 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001892 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001893 """
1894 cert = load_certificate(FILETYPE_PEM, self.pemData)
1895 subj = cert.get_issuer()
1896 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001897 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001898 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001899 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001900 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1901 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001902
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001903 def test_set_issuer_wrong_args(self):
1904 """
Alex Gaynor31287502015-09-05 16:11:27 -04001905 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1906 the wrong number of arguments or an argument not of type
1907 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001908 """
1909 cert = X509()
1910 self.assertRaises(TypeError, cert.set_issuer)
1911 self.assertRaises(TypeError, cert.set_issuer, None)
1912 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1913
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001914 def test_set_issuer(self):
1915 """
Alex Gaynor31287502015-09-05 16:11:27 -04001916 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1917 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001918 """
1919 cert = X509()
1920 name = cert.get_issuer()
1921 name.C = 'AU'
1922 name.O = 'Unit Tests'
1923 cert.set_issuer(name)
1924 self.assertEquals(
1925 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001926 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001927
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001928 def test_get_pubkey_uninitialized(self):
1929 """
Alex Gaynor31287502015-09-05 16:11:27 -04001930 When called on a certificate with no public key,
1931 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001932 """
1933 cert = X509()
1934 self.assertRaises(Error, cert.get_pubkey)
1935
Alex Gaynor7778e792016-07-03 23:38:48 -04001936 def test_set_pubkey_wrong_type(self):
1937 """
1938 :obj:`X509.set_pubkey` raises :obj:`TypeError` when given an object of
1939 the wrong type.
1940 """
1941 cert = X509()
1942 with pytest.raises(TypeError):
1943 cert.set_pubkey(object())
1944
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001945 def test_subject_name_hash_wrong_args(self):
1946 """
Alex Gaynor31287502015-09-05 16:11:27 -04001947 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1948 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001949 """
1950 cert = X509()
1951 self.assertRaises(TypeError, cert.subject_name_hash, None)
1952
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001953 def test_subject_name_hash(self):
1954 """
Alex Gaynor31287502015-09-05 16:11:27 -04001955 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1956 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001957 """
1958 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001959 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001960 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001961 [3350047874, # OpenSSL 0.9.8, MD5
1962 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001963 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001964
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001965 def test_get_signature_algorithm(self):
1966 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001967 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001968 the algorithm used to sign the certificate.
1969 """
1970 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001971 self.assertEqual(
1972 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001973
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001974 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001975 """
Alex Gaynor31287502015-09-05 16:11:27 -04001976 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1977 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001978 """
1979 # This certificate has been modified to indicate a bogus OID in the
1980 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001981 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001982-----BEGIN CERTIFICATE-----
1983MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1984EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1985cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1986MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1987EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1988CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1989AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1990+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1991hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1992BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1993FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1994dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1995aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1996MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1997jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1998PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1999tgI5
2000-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002001""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04002002 cert = load_certificate(FILETYPE_PEM, certPEM)
2003 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002004
Alex Gaynor37726112016-07-04 09:51:32 -04002005 def test_sign_bad_pubkey_type(self):
2006 """
2007 :obj:`X509.sign` raises :obj:`TypeError` when called with the wrong
2008 type.
2009 """
2010 cert = X509()
2011 with pytest.raises(TypeError):
2012 cert.sign(object(), b"sha256")
2013
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002014
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002015class X509StoreTests(TestCase):
2016 """
2017 Test for :py:obj:`OpenSSL.crypto.X509Store`.
2018 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002019
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002020 def test_type(self):
2021 """
2022 :py:obj:`X509StoreType` is a type object.
2023 """
2024 self.assertIdentical(X509Store, X509StoreType)
2025 self.assertConsistentType(X509Store, 'X509Store')
2026
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002027 def test_add_cert_wrong_args(self):
2028 store = X509Store()
2029 self.assertRaises(TypeError, store.add_cert)
2030 self.assertRaises(TypeError, store.add_cert, object())
2031 self.assertRaises(TypeError, store.add_cert, X509(), object())
2032
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002033 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002034 """
2035 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
2036 certificate store.
2037 """
2038 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002039 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002040 store.add_cert(cert)
2041
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002042 def test_add_cert_rejects_duplicate(self):
2043 """
Alex Gaynor31287502015-09-05 16:11:27 -04002044 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
2045 an attempt is made to add the same certificate to the store more than
2046 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002047 """
2048 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2049 store = X509Store()
2050 store.add_cert(cert)
2051 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002052
2053
Rick Dean623ee362009-07-17 12:22:16 -05002054class PKCS12Tests(TestCase):
2055 """
Alex Gaynor31287502015-09-05 16:11:27 -04002056 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
2057 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002058 """
2059 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
2060
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002061 def test_type(self):
2062 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002063 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002064 """
2065 self.assertIdentical(PKCS12, PKCS12Type)
2066 self.assertConsistentType(PKCS12, 'PKCS12')
2067
Rick Deanf94096c2009-07-18 14:23:06 -05002068 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002069 """
Alex Gaynor31287502015-09-05 16:11:27 -04002070 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
2071 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05002072 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002073 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05002074 self.assertEqual(None, p12.get_certificate())
2075 self.assertEqual(None, p12.get_privatekey())
2076 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05002077 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05002078
2079 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002080 """
Alex Gaynor31287502015-09-05 16:11:27 -04002081 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
2082 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
2083 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
2084 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05002085 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002086 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05002087 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002088 self.assertRaises(TypeError, p12.set_certificate, PKey())
2089 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05002090 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002091 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
2092 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05002093 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
2094 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
2095 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04002096 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05002097 self.assertRaises(TypeError, p12.set_friendlyname, 6)
2098 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05002099
2100 def test_key_only(self):
2101 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002102 A :py:obj:`PKCS12` with only a private key can be exported using
2103 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002104 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002105 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002106 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002107 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002108 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05002109 self.assertEqual(None, p12.get_certificate())
2110 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002111 try:
2112 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2113 except Error:
2114 # Some versions of OpenSSL will throw an exception
2115 # for this nearly useless PKCS12 we tried to generate:
2116 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2117 return
Rick Dean623ee362009-07-17 12:22:16 -05002118 p12 = load_pkcs12(dumped_p12, passwd)
2119 self.assertEqual(None, p12.get_ca_certificates())
2120 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002121
2122 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2123 # future this will be improved.
2124 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05002125
2126 def test_cert_only(self):
2127 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002128 A :py:obj:`PKCS12` with only a certificate can be exported using
2129 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002130 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002131 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002132 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002133 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002134 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05002135 self.assertEqual(cert, p12.get_certificate())
2136 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002137 try:
2138 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2139 except Error:
2140 # Some versions of OpenSSL will throw an exception
2141 # for this nearly useless PKCS12 we tried to generate:
2142 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2143 return
Rick Dean623ee362009-07-17 12:22:16 -05002144 p12 = load_pkcs12(dumped_p12, passwd)
2145 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002146
2147 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
2148 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2149
2150 # Oh ho. It puts the certificate into the ca certificates list, in
2151 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2152 # that to check to see if it reconstructed the certificate we expected
2153 # it to. At some point, hopefully this will change so that
2154 # p12.get_certificate() is actually what returns the loaded
2155 # certificate.
2156 self.assertEqual(
2157 cleartextCertificatePEM,
2158 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002159
Alex Gaynor31287502015-09-05 16:11:27 -04002160 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2161 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002162 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002163 Generate a PKCS12 object with components from PEM. Verify that the set
2164 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002165 """
Rick Deanf94096c2009-07-18 14:23:06 -05002166 p12 = PKCS12()
2167 if cert_pem:
2168 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2169 self.assertEqual(ret, None)
2170 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002171 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002172 self.assertEqual(ret, None)
2173 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002174 ret = p12.set_ca_certificates(
2175 (load_certificate(FILETYPE_PEM, ca_pem),)
2176 )
Rick Deanf94096c2009-07-18 14:23:06 -05002177 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002178 if friendly_name:
2179 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002180 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002181 return p12
2182
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002183 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002184 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002185 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002186 Use openssl program to confirm three components are recoverable from a
2187 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002188 """
2189 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002190 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002191 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2192 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002193 self.assertEqual(recovered_key[-len(key):], key)
2194 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002195 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002196 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2197 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002198 self.assertEqual(recovered_cert[-len(cert):], cert)
2199 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002200 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002201 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2202 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002203 self.assertEqual(recovered_cert[-len(ca):], ca)
2204
Stephen Holsapple38482622014-04-05 20:29:34 -07002205 def verify_pkcs12_container(self, p12):
2206 """
2207 Verify that the PKCS#12 container contains the correct client
2208 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002209
2210 :param p12: The PKCS12 instance to verify.
2211 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002212 """
2213 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2214 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002215 self.assertEqual(
2216 (client_cert_pem, client_key_pem, None),
2217 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002218
Rick Deanf94096c2009-07-18 14:23:06 -05002219 def test_load_pkcs12(self):
2220 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002221 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002222 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002223 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002224 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002225 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002226 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002227 pem,
2228 b"pkcs12",
2229 b"-export",
2230 b"-clcerts",
2231 b"-passout",
2232 b"pass:" + passwd
2233 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002234 p12 = load_pkcs12(p12_str, passphrase=passwd)
2235 self.verify_pkcs12_container(p12)
2236
Abraham Martinc5484ba2015-03-25 15:33:05 +00002237 def test_load_pkcs12_text_passphrase(self):
2238 """
2239 A PKCS12 string generated using the openssl command line can be loaded
2240 with :py:obj:`load_pkcs12` and its components extracted and examined.
2241 Using text as passphrase instead of bytes. DeprecationWarning expected.
2242 """
2243 pem = client_key_pem + client_cert_pem
2244 passwd = b"whatever"
2245 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2246 b"-passout", b"pass:" + passwd)
2247 with catch_warnings(record=True) as w:
2248 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002249 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002250
2251 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002252 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002253 WARNING_TYPE_EXPECTED
2254 ),
2255 str(w[-1].message)
2256 )
2257 self.assertIs(w[-1].category, DeprecationWarning)
2258
Abraham Martinc5484ba2015-03-25 15:33:05 +00002259 self.verify_pkcs12_container(p12)
2260
Stephen Holsapple38482622014-04-05 20:29:34 -07002261 def test_load_pkcs12_no_passphrase(self):
2262 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002263 A PKCS12 string generated using openssl command line can be loaded with
2264 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2265 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002266 """
2267 pem = client_key_pem + client_cert_pem
2268 p12_str = _runopenssl(
2269 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2270 p12 = load_pkcs12(p12_str)
2271 self.verify_pkcs12_container(p12)
2272
Stephen Holsapple38482622014-04-05 20:29:34 -07002273 def _dump_and_load(self, dump_passphrase, load_passphrase):
2274 """
2275 A helper method to dump and load a PKCS12 object.
2276 """
2277 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2278 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2279 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2280
Stephen Holsapple38482622014-04-05 20:29:34 -07002281 def test_load_pkcs12_null_passphrase_load_empty(self):
2282 """
2283 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002284 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002285 extracted and examined.
2286 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002287 self.verify_pkcs12_container(
2288 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002289
Stephen Holsapple38482622014-04-05 20:29:34 -07002290 def test_load_pkcs12_null_passphrase_load_null(self):
2291 """
2292 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002293 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002294 extracted and examined.
2295 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002296 self.verify_pkcs12_container(
2297 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002298
Stephen Holsapple38482622014-04-05 20:29:34 -07002299 def test_load_pkcs12_empty_passphrase_load_empty(self):
2300 """
2301 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002302 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002303 extracted and examined.
2304 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002305 self.verify_pkcs12_container(
2306 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002307
Stephen Holsapple38482622014-04-05 20:29:34 -07002308 def test_load_pkcs12_empty_passphrase_load_null(self):
2309 """
2310 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002311 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002312 extracted and examined.
2313 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002314 self.verify_pkcs12_container(
2315 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002316
Rick Deanee568302009-07-24 09:56:29 -05002317 def test_load_pkcs12_garbage(self):
2318 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002319 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2320 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002321 """
2322 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002323 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002324 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2325 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002326
Rick Deanf94096c2009-07-18 14:23:06 -05002327 def test_replace(self):
2328 """
Alex Gaynor31287502015-09-05 16:11:27 -04002329 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2330 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002331 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002332 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002333 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2334 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2335 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002336 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002337 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002338 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002339 self.assertEqual(1, len(p12.get_ca_certificates()))
2340 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002341 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002342 self.assertEqual(2, len(p12.get_ca_certificates()))
2343 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2344 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2345
Rick Deanf94096c2009-07-18 14:23:06 -05002346 def test_friendly_name(self):
2347 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002348 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002349 :py:obj:`PKCS12.get_friendlyname` and
2350 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2351 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002352 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002353 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002354 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002355 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002356 p12.set_friendlyname(friendly_name)
2357 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002358 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002359 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002360 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002361 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002362 # We would use the openssl program to confirm the friendly
2363 # name, but it is not possible. The pkcs12 command
2364 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002365 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002366 self.check_recovery(
2367 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2368 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002369
Rick Deanf94096c2009-07-18 14:23:06 -05002370 def test_various_empty_passphrases(self):
2371 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002372 Test that missing, None, and '' passphrases are identical for PKCS12
2373 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002374 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002375 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002376 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002377 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2378 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2379 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2380 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2381 self.check_recovery(
2382 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2383 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002384
Rick Deanf94096c2009-07-18 14:23:06 -05002385 def test_removing_ca_cert(self):
2386 """
Alex Gaynor31287502015-09-05 16:11:27 -04002387 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2388 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002389 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002390 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2391 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002392 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002393
Rick Deanf94096c2009-07-18 14:23:06 -05002394 def test_export_without_mac(self):
2395 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002396 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002397 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002398 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002399 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002400 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002401 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002402 self.check_recovery(
2403 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002404 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002405
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002406 def test_load_without_mac(self):
2407 """
2408 Loading a PKCS12 without a MAC does something other than crash.
2409 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002410 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002411 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2412 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002413 try:
2414 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2415 # The person who generated this PCKS12 should be flogged,
2416 # or better yet we should have a means to determine
2417 # whether a PCKS12 had a MAC that was verified.
2418 # Anyway, libopenssl chooses to allow it, so the
2419 # pyopenssl binding does as well.
2420 self.assertTrue(isinstance(recovered_p12, PKCS12))
2421 except Error:
2422 # Failing here with an exception is preferred as some openssl
2423 # versions do.
2424 pass
Rick Dean623ee362009-07-17 12:22:16 -05002425
Rick Dean25bcc1f2009-07-20 11:53:13 -05002426 def test_zero_len_list_for_ca(self):
2427 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002428 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002429 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002430 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002431 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002432 p12.set_ca_certificates([])
2433 self.assertEqual((), p12.get_ca_certificates())
2434 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2435 self.check_recovery(
2436 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2437 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002438
Rick Deanf94096c2009-07-18 14:23:06 -05002439 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002440 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002441 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002442 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002443 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002444 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002445 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002446 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002447
Abraham Martinc5484ba2015-03-25 15:33:05 +00002448 def test_export_without_bytes(self):
2449 """
2450 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2451 """
2452 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2453
2454 with catch_warnings(record=True) as w:
2455 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002456 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002457 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002458 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002459 WARNING_TYPE_EXPECTED
2460 ),
2461 str(w[-1].message)
2462 )
2463 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002464 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002465 dumped_p12,
2466 key=server_key_pem,
2467 cert=server_cert_pem,
2468 passwd=b"randomtext"
2469 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002470
Rick Deanf94096c2009-07-18 14:23:06 -05002471 def test_key_cert_mismatch(self):
2472 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002473 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002474 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002475 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002476 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2477 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002478
2479
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002480# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002481_cmdLineQuoteRe = re.compile(br'(\\*)"')
2482_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002483
2484
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002485def cmdLineQuote(s):
2486 """
2487 Internal method for quoting a single command-line argument.
2488
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002489 See http://www.perlmonks.org/?node_id=764004
2490
Jonathan Ballet648875f2011-07-16 14:14:58 +09002491 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002492 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002493 cmd.exe-style quoting
2494
Jonathan Ballet648875f2011-07-16 14:14:58 +09002495 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002496 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002497 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002498 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2499 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002500
2501
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002502def quoteArguments(arguments):
2503 """
2504 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002505 a similar API. This allows the list passed to
2506 :py:obj:`reactor.spawnProcess` to match the child process's
2507 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002508
Jonathan Ballet648875f2011-07-16 14:14:58 +09002509 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002510 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002511
Jonathan Ballet648875f2011-07-16 14:14:58 +09002512 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002513 :return: A space-delimited string containing quoted versions of
2514 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002515 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002516 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002517
2518
Rick Dean4c9ad612009-07-17 15:05:22 -05002519def _runopenssl(pem, *args):
2520 """
2521 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002522 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002523 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002524 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002525 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002526 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2527 for arg in args
2528 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002529 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002530 command = b"openssl " + quoteArguments(args)
2531 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002532 proc.stdin.write(pem)
2533 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002534 output = proc.stdout.read()
2535 proc.stdout.close()
2536 proc.wait()
2537 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002538
2539
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002540class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002541 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002542 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002543 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002544 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002545 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002546 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002547 """
2548 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002549
2550 assert True is key._only_public
2551 assert 2048 == key.bits()
2552 assert TYPE_RSA == key.type()
2553
2554 def test_invalid_type(self):
2555 """
2556 load_publickey doesn't support FILETYPE_TEXT.
2557 """
2558 with pytest.raises(ValueError):
2559 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2560
2561 def test_invalid_key_format(self):
2562 """
2563 load_publickey explodes on incorrect keys.
2564 """
2565 with pytest.raises(Error):
2566 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2567
2568 def test_tolerates_unicode_strings(self):
2569 """
2570 load_publickey works with text strings, not just bytes.
2571 """
2572 serialized = cleartextPublicKeyPEM.decode('ascii')
2573 key = load_publickey(FILETYPE_PEM, serialized)
2574 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2575
2576 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002577
2578
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002579class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002580 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002581 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002582
2583 Add new tests to `TestFunctions` above.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002584 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002585
2586 def test_load_privatekey_invalid_format(self):
2587 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002588 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2589 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002590 """
2591 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2592
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002593 def test_load_privatekey_invalid_passphrase_type(self):
2594 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002595 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2596 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002597 """
2598 self.assertRaises(
2599 TypeError,
2600 load_privatekey,
2601 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2602
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002603 def test_load_privatekey_wrong_args(self):
2604 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002605 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2606 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002607 """
2608 self.assertRaises(TypeError, load_privatekey)
2609
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002610 def test_load_privatekey_wrongPassphrase(self):
2611 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002612 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2613 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002614 """
2615 self.assertRaises(
2616 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002617 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002618
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002619 def test_load_privatekey_passphraseWrongType(self):
2620 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002621 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2622 a passphrase with a private key encoded in a format, that doesn't
2623 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002624 """
2625 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2626 blob = dump_privatekey(FILETYPE_ASN1, key)
2627 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002628 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002629
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002630 def test_load_privatekey_passphrase(self):
2631 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002632 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2633 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002634 """
2635 key = load_privatekey(
2636 FILETYPE_PEM, encryptedPrivateKeyPEM,
2637 encryptedPrivateKeyPEMPassphrase)
2638 self.assertTrue(isinstance(key, PKeyType))
2639
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002640 def test_load_privatekey_passphrase_exception(self):
2641 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002642 If the passphrase callback raises an exception, that exception is
2643 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002644 """
2645 def cb(ignored):
2646 raise ArithmeticError
2647
Alex Gaynor791212d2015-09-05 15:46:08 -04002648 with pytest.raises(ArithmeticError):
2649 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002650
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002651 def test_load_privatekey_wrongPassphraseCallback(self):
2652 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002653 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2654 is passed an encrypted PEM and a passphrase callback which returns an
2655 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002656 """
2657 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002658
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002659 def cb(*a):
2660 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002661 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002662 self.assertRaises(
2663 Error,
2664 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2665 self.assertTrue(called)
2666
2667 def test_load_privatekey_passphraseCallback(self):
2668 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002669 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2670 encrypted PEM string if given a passphrase callback which returns the
2671 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002672 """
2673 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002674
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002675 def cb(writing):
2676 called.append(writing)
2677 return encryptedPrivateKeyPEMPassphrase
2678 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2679 self.assertTrue(isinstance(key, PKeyType))
2680 self.assertEqual(called, [False])
2681
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002682 def test_load_privatekey_passphrase_wrong_return_type(self):
2683 """
2684 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2685 callback returns something other than a byte string.
2686 """
2687 self.assertRaises(
2688 ValueError,
2689 load_privatekey,
2690 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2691
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002692 def test_dump_privatekey_wrong_args(self):
2693 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002694 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2695 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002696 """
2697 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002698 # If cipher name is given, password is required.
2699 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002700 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002701
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002702 def test_dump_privatekey_unknown_cipher(self):
2703 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002704 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2705 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002706 """
2707 key = PKey()
2708 key.generate_key(TYPE_RSA, 512)
2709 self.assertRaises(
2710 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002711 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002712
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002713 def test_dump_privatekey_invalid_passphrase_type(self):
2714 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002715 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2716 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002717 """
2718 key = PKey()
2719 key.generate_key(TYPE_RSA, 512)
2720 self.assertRaises(
2721 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002722 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002723
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002724 def test_dump_privatekey_invalid_filetype(self):
2725 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002726 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2727 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002728 """
2729 key = PKey()
2730 key.generate_key(TYPE_RSA, 512)
2731 self.assertRaises(ValueError, dump_privatekey, 100, key)
2732
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002733 def test_load_privatekey_passphraseCallbackLength(self):
2734 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002735 :py:obj:`crypto.load_privatekey` should raise an error when the
2736 passphrase provided by the callback is too long, not silently truncate
2737 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002738 """
2739 def cb(ignored):
2740 return "a" * 1025
2741
Alex Gaynor791212d2015-09-05 15:46:08 -04002742 with pytest.raises(ValueError):
2743 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002744
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002745 def test_dump_privatekey_passphrase(self):
2746 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002747 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2748 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002749 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002750 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002751 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002752 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2753 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002754 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2755 self.assertTrue(isinstance(loadedKey, PKeyType))
2756 self.assertEqual(loadedKey.type(), key.type())
2757 self.assertEqual(loadedKey.bits(), key.bits())
2758
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002759 def test_dump_privatekey_passphraseWrongType(self):
2760 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002761 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2762 a passphrase with a private key encoded in a format, that doesn't
2763 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002764 """
2765 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002766 with pytest.raises(ValueError):
2767 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002768
Rick Dean5b7b6372009-04-01 11:34:06 -05002769 def test_dump_certificate(self):
2770 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002771 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002772 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002773 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002774 cert = load_certificate(FILETYPE_PEM, pemData)
2775 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2776 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2777 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002778 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002779 self.assertEqual(dumped_der, good_der)
2780 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2781 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2782 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2783 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002784 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002785 self.assertEqual(dumped_text, good_text)
2786
Alex Gaynor37726112016-07-04 09:51:32 -04002787 def test_dump_certificate_bad_type(self):
2788 """
2789 :obj:`dump_certificate` raises a :obj:`ValueError` if it's called with
2790 a bad type.
2791 """
2792 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2793 with pytest.raises(ValueError):
2794 dump_certificate(object(), cert)
2795
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002796 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002797 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002798 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002799 """
2800 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002801 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002802 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2803 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002804
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002805 def test_dump_privatekey_asn1(self):
2806 """
2807 :py:obj:`dump_privatekey` writes a DER
2808 """
2809 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2810 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2811
Rick Dean5b7b6372009-04-01 11:34:06 -05002812 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002813 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002814 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002815 self.assertEqual(dumped_der, good_der)
2816 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2817 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2818 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002819
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002820 def test_dump_privatekey_text(self):
2821 """
2822 :py:obj:`dump_privatekey` writes a text
2823 """
2824 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2825 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2826
Rick Dean5b7b6372009-04-01 11:34:06 -05002827 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002828 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002829 self.assertEqual(dumped_text, good_text)
2830
Cory Benfield6492f7c2015-10-27 16:57:58 +09002831 def test_dump_publickey_pem(self):
2832 """
Cory Benfield11c10192015-10-27 17:23:03 +09002833 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002834 """
2835 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2836 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002837 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002838
2839 def test_dump_publickey_asn1(self):
2840 """
Cory Benfield11c10192015-10-27 17:23:03 +09002841 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002842 """
2843 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2844 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2845 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2846 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002847 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002848
Cory Benfielde02c7d82015-10-27 17:34:49 +09002849 def test_dump_publickey_invalid_type(self):
2850 """
2851 dump_publickey doesn't support FILETYPE_TEXT.
2852 """
2853 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2854
2855 with pytest.raises(ValueError):
2856 dump_publickey(FILETYPE_TEXT, key)
2857
Rick Dean5b7b6372009-04-01 11:34:06 -05002858 def test_dump_certificate_request(self):
2859 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002860 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002861 """
Alex Gaynor31287502015-09-05 16:11:27 -04002862 req = load_certificate_request(
2863 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002864 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2865 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2866 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002867 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002868 self.assertEqual(dumped_der, good_der)
2869 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2870 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2871 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2872 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002873 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002874 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002875 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002876
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002877 def test_dump_privatekey_passphraseCallback(self):
2878 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002879 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2880 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002881 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002882 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002883 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002884
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002885 def cb(writing):
2886 called.append(writing)
2887 return passphrase
2888 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002889 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2890 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002891 self.assertEqual(called, [True])
2892 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2893 self.assertTrue(isinstance(loadedKey, PKeyType))
2894 self.assertEqual(loadedKey.type(), key.type())
2895 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002896
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002897 def test_dump_privatekey_passphrase_exception(self):
2898 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002899 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002900 by the passphrase callback.
2901 """
2902 def cb(ignored):
2903 raise ArithmeticError
2904
2905 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002906 with pytest.raises(ArithmeticError):
2907 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002908
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002909 def test_dump_privatekey_passphraseCallbackLength(self):
2910 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002911 :py:obj:`crypto.dump_privatekey` should raise an error when the
2912 passphrase provided by the callback is too long, not silently truncate
2913 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002914 """
2915 def cb(ignored):
2916 return "a" * 1025
2917
2918 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002919 with pytest.raises(ValueError):
2920 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002921
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002922 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002923 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002924 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2925 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002926 """
2927 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2928 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2929
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002930 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002931 """
2932 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2933 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2934 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002935 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2936 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2937
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002938 def test_load_pkcs7_data_invalid(self):
2939 """
2940 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2941 :py:obj:`Error` is raised.
2942 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002943 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002944
Alex Gaynor09a386e2016-07-03 09:32:44 -04002945 def test_load_pkcs7_type_invalid(self):
2946 """
2947 If the type passed to :obj:`load_pkcs7_data`, :obj:`ValueError` is
2948 raised.
2949 """
2950 with pytest.raises(ValueError):
2951 load_pkcs7_data(object(), b"foo")
2952
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002953
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002954class LoadCertificateTests(TestCase):
2955 """
2956 Tests for :py:obj:`load_certificate_request`.
2957 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002958
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002959 def test_badFileType(self):
2960 """
2961 If the file type passed to :py:obj:`load_certificate_request` is
2962 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2963 :py:class:`ValueError` is raised.
2964 """
Alex Gaynor7778e792016-07-03 23:38:48 -04002965 with pytest.raises(ValueError):
2966 load_certificate_request(object(), b"")
2967 with pytest.raises(ValueError):
2968 load_certificate(object(), b"")
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002969
Alex Gaynor37726112016-07-04 09:51:32 -04002970 def test_bad_certificate(self):
2971 """
2972 If the bytes passed to :obj:`load_certificate` are not a valid
2973 certificate, an exception is raised.
2974 """
2975 with pytest.raises(Error):
2976 load_certificate(FILETYPE_ASN1, b"lol")
2977
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002978
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002979class PKCS7Tests(TestCase):
2980 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002981 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002982 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002983
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002984 def test_type(self):
2985 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002986 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002987 """
2988 self.assertTrue(isinstance(PKCS7Type, type))
2989 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2990
2991 # XXX This doesn't currently work.
2992 # self.assertIdentical(PKCS7, PKCS7Type)
2993
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002994 # XXX Opposite results for all these following methods
2995
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002996 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002997 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002998 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2999 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003000 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003001 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3002 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
3003
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003004 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003005 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003006 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
3007 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003008 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003009 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3010 self.assertTrue(pkcs7.type_is_signed())
3011
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003012 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003013 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003014 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
3015 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003016 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003017 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3018 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
3019
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003020 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003021 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003022 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
3023 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003024 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003025 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3026 self.assertFalse(pkcs7.type_is_enveloped())
3027
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003028 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003029 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003030 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
3031 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003032 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003033 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3034 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
3035
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003036 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003037 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003038 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
3039 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003040 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003041 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3042 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
3043
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003044 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003045 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003046 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
3047 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003048 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003049 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3050 self.assertFalse(pkcs7.type_is_data())
3051
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003052 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003053 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003054 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
3055 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003056 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003057 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3058 self.assertRaises(TypeError, pkcs7.type_is_data, None)
3059
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003060 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003061 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003062 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
3063 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003064 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003065 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3066 self.assertRaises(TypeError, pkcs7.get_type_name, None)
3067
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003068 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003069 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003070 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
3071 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003072 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003073 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04003074 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003075
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003076 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003077 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003078 If an attribute other than one of the methods tested here is accessed
3079 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
3080 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003081 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003082 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3083 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
3084
3085
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003086class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003087 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003088 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003089 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003090
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003091 def signable(self):
3092 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003093 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003094 """
3095 return NetscapeSPKI()
3096
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003097 def test_type(self):
3098 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003099 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
3100 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003101 """
3102 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
3103 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
3104
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003105 def test_construction(self):
3106 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003107 :py:obj:`NetscapeSPKI` returns an instance of
3108 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003109 """
3110 nspki = NetscapeSPKI()
3111 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
3112
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003113 def test_invalid_attribute(self):
3114 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003115 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
3116 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003117 """
3118 nspki = NetscapeSPKI()
3119 self.assertRaises(AttributeError, lambda: nspki.foo)
3120
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003121 def test_b64_encode(self):
3122 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003123 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
3124 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003125 """
3126 nspki = NetscapeSPKI()
3127 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003128 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003129
3130
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003131class TestRevoked(object):
3132 """
3133 Please add test cases for the Revoked class here if possible. This class
3134 holds the new py.test style tests.
3135 """
3136 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3137 """
3138 The get_reason method on the Revoked class checks to see if the
3139 extension is NID_crl_reason and should skip it otherwise. This test
3140 loads a CRL with extensions it should ignore.
3141 """
3142 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3143 revoked = crl.get_revoked()
3144 reason = revoked[1].get_reason()
3145 assert reason == b'Unspecified'
3146
3147 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3148 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3149 revoked = crl.get_revoked()
3150 revoked[1].set_reason(None)
3151 reason = revoked[1].get_reason()
3152 assert reason is None
3153
3154
Rick Dean536ba022009-07-24 23:57:27 -05003155class RevokedTests(TestCase):
3156 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003157 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3158 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003159 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003160
Rick Dean536ba022009-07-24 23:57:27 -05003161 def test_construction(self):
3162 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003163 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003164 that it is empty.
3165 """
3166 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003167 self.assertTrue(isinstance(revoked, Revoked))
3168 self.assertEquals(type(revoked), Revoked)
3169 self.assertEquals(revoked.get_serial(), b('00'))
3170 self.assertEquals(revoked.get_rev_date(), None)
3171 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003172
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003173 def test_construction_wrong_args(self):
3174 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003175 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3176 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003177 """
3178 self.assertRaises(TypeError, Revoked, None)
3179 self.assertRaises(TypeError, Revoked, 1)
3180 self.assertRaises(TypeError, Revoked, "foo")
3181
Rick Dean536ba022009-07-24 23:57:27 -05003182 def test_serial(self):
3183 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003184 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003185 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003186 with grace.
3187 """
3188 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003189 ret = revoked.set_serial(b('10b'))
3190 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003191 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003192 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003193
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003194 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003195 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003196 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003197
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003198 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003199 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003200 self.assertRaises(TypeError, revoked.get_serial, 1)
3201 self.assertRaises(TypeError, revoked.get_serial, None)
3202 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003203
Rick Dean536ba022009-07-24 23:57:27 -05003204 def test_date(self):
3205 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003206 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003207 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003208 with grace.
3209 """
3210 revoked = Revoked()
3211 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003212 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003213
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003214 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003215 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003216 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003217 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003218 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003219
Rick Dean6385faf2009-07-26 00:07:47 -05003220 def test_reason(self):
3221 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003222 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003223 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003224 as "set". Likewise, each reason of all_reasons() must work.
3225 """
3226 revoked = Revoked()
3227 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003228 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003229 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003230 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003231 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003232 self.assertEquals(
3233 reason.lower().replace(b(' '), b('')),
3234 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003235 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003236
3237 revoked.set_reason(None)
3238 self.assertEqual(revoked.get_reason(), None)
3239
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003240 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003241 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003242 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003243 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003244 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003245 """
3246 revoked = Revoked()
3247 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003248 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003249
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003250 def test_get_reason_wrong_arguments(self):
3251 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003252 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3253 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003254 """
3255 revoked = Revoked()
3256 self.assertRaises(TypeError, revoked.get_reason, None)
3257 self.assertRaises(TypeError, revoked.get_reason, 1)
3258 self.assertRaises(TypeError, revoked.get_reason, "foo")
3259
3260
Rick Dean536ba022009-07-24 23:57:27 -05003261class CRLTests(TestCase):
3262 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003263 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003264 """
3265 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3266 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3267
Dan Sully44e767a2016-06-04 18:05:27 -07003268 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3269 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3270 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3271 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3272 intermediate_server_cert = load_certificate(
3273 FILETYPE_PEM, intermediate_server_cert_pem)
3274 intermediate_server_key = load_privatekey(
3275 FILETYPE_PEM, intermediate_server_key_pem)
3276
Rick Dean536ba022009-07-24 23:57:27 -05003277 def test_construction(self):
3278 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003279 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003280 that it is empty
3281 """
3282 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003283 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003284 self.assertEqual(crl.get_revoked(), None)
3285
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003286 def test_construction_wrong_args(self):
3287 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003288 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3289 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003290 """
3291 self.assertRaises(TypeError, CRL, 1)
3292 self.assertRaises(TypeError, CRL, "")
3293 self.assertRaises(TypeError, CRL, None)
3294
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003295 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003296 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003297 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003298 """
3299 crl = CRL()
3300 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003301 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003302 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003303 revoked.set_serial(b('3ab'))
3304 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003305 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003306 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003307
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003308 def test_export_pem(self):
3309 """
3310 If not passed a format, ``CRL.export`` returns a "PEM" format string
3311 representing a serial number, a revoked reason, and certificate issuer
3312 information.
3313 """
3314 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003315 # PEM format
3316 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003317 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003318
3319 # These magic values are based on the way the CRL above was constructed
3320 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003321 text.index(b('Serial Number: 03AB'))
3322 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003323 text.index(
3324 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3325 )
3326
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003327 def test_export_der(self):
3328 """
3329 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3330 "DER" format string representing a serial number, a revoked reason, and
3331 certificate issuer information.
3332 """
3333 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003334
3335 # DER format
3336 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003337 text = _runopenssl(
3338 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3339 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003340 text.index(b('Serial Number: 03AB'))
3341 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003342 text.index(
3343 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3344 )
3345
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003346 def test_export_text(self):
3347 """
3348 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3349 text format string like the one produced by the openssl command line
3350 tool.
3351 """
3352 crl = self._get_crl()
3353
3354 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3355 text = _runopenssl(
3356 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3357 )
Rick Dean536ba022009-07-24 23:57:27 -05003358
3359 # text format
3360 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3361 self.assertEqual(text, dumped_text)
3362
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003363 def test_export_custom_digest(self):
3364 """
3365 If passed the name of a digest function, ``CRL.export`` uses a
3366 signature algorithm based on that digest function.
3367 """
3368 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003369 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003370 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3371 text.index(b('Signature Algorithm: sha1'))
3372
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003373 def test_export_md5_digest(self):
3374 """
3375 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3376 not emit a deprecation warning.
3377 """
3378 crl = self._get_crl()
3379 with catch_warnings(record=True) as catcher:
3380 simplefilter("always")
3381 self.assertEqual(0, len(catcher))
3382 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3383 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3384 text.index(b('Signature Algorithm: md5'))
3385
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003386 def test_export_default_digest(self):
3387 """
3388 If not passed the name of a digest function, ``CRL.export`` uses a
3389 signature algorithm based on MD5 and emits a deprecation warning.
3390 """
3391 crl = self._get_crl()
3392 with catch_warnings(record=True) as catcher:
3393 simplefilter("always")
3394 dumped_crl = crl.export(self.cert, self.pkey)
3395 self.assertEqual(
3396 "The default message digest (md5) is deprecated. "
3397 "Pass the name of a message digest explicitly.",
3398 str(catcher[0].message),
3399 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003400 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3401 text.index(b('Signature Algorithm: md5'))
3402
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003403 def test_export_invalid(self):
3404 """
3405 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003406 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003407 """
3408 crl = CRL()
3409 self.assertRaises(Error, crl.export, X509(), PKey())
3410
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003411 def test_add_revoked_keyword(self):
3412 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003413 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003414 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003415 """
3416 crl = CRL()
3417 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003418 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003419 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003420 crl.add_revoked(revoked=revoked)
3421 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3422
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003423 def test_export_wrong_args(self):
3424 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003425 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003426 four arguments, or with arguments other than the certificate,
3427 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003428 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003429 """
3430 crl = CRL()
3431 self.assertRaises(TypeError, crl.export)
3432 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003433 with pytest.raises(TypeError):
3434 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3435 with pytest.raises(TypeError):
3436 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3437 with pytest.raises(TypeError):
3438 crl.export(self.cert, None, FILETYPE_PEM, 10)
3439 with pytest.raises(TypeError):
3440 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003441 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3442
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003443 def test_export_unknown_filetype(self):
3444 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003445 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003446 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3447 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003448 """
3449 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003450 with pytest.raises(ValueError):
3451 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003452
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003453 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003454 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003455 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003456 in a :py:obj:`ValueError` being raised.
3457 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003458 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003459 self.assertRaises(
3460 ValueError,
3461 crl.export,
3462 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3463 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003464
Rick Dean536ba022009-07-24 23:57:27 -05003465 def test_get_revoked(self):
3466 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003467 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003468 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3469 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003470 """
3471 crl = CRL()
3472
3473 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003474 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003475 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003476 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003477 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003478 revoked.set_serial(b('100'))
3479 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003480 crl.add_revoked(revoked)
3481
3482 revs = crl.get_revoked()
3483 self.assertEqual(len(revs), 2)
3484 self.assertEqual(type(revs[0]), Revoked)
3485 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003486 self.assertEqual(revs[0].get_serial(), b('03AB'))
3487 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003488 self.assertEqual(revs[0].get_rev_date(), now)
3489 self.assertEqual(revs[1].get_rev_date(), now)
3490
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003491 def test_get_revoked_wrong_args(self):
3492 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003493 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3494 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003495 """
3496 crl = CRL()
3497 self.assertRaises(TypeError, crl.get_revoked, None)
3498 self.assertRaises(TypeError, crl.get_revoked, 1)
3499 self.assertRaises(TypeError, crl.get_revoked, "")
3500 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3501
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003502 def test_add_revoked_wrong_args(self):
3503 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003504 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3505 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003506 """
3507 crl = CRL()
3508 self.assertRaises(TypeError, crl.add_revoked)
3509 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3510 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3511
Rick Dean536ba022009-07-24 23:57:27 -05003512 def test_load_crl(self):
3513 """
3514 Load a known CRL and inspect its revocations. Both
3515 PEM and DER formats are loaded.
3516 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003517 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003518 revs = crl.get_revoked()
3519 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003520 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003521 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003522 self.assertEqual(revs[1].get_serial(), b('0100'))
3523 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003524
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003525 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003526 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003527 revs = crl.get_revoked()
3528 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003529 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003530 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003531 self.assertEqual(revs[1].get_serial(), b('0100'))
3532 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003533
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003534 def test_load_crl_wrong_args(self):
3535 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003536 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3537 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003538 """
3539 self.assertRaises(TypeError, load_crl)
3540 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3541 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3542
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003543 def test_load_crl_bad_filetype(self):
3544 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003545 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3546 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003547 """
3548 self.assertRaises(ValueError, load_crl, 100, crlData)
3549
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003550 def test_load_crl_bad_data(self):
3551 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003552 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3553 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003554 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003555 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003556
Dan Sully44e767a2016-06-04 18:05:27 -07003557 def test_get_issuer(self):
3558 """
3559 Load a known CRL and assert its issuer's common name is
3560 what we expect from the encoded crlData string.
3561 """
3562 crl = load_crl(FILETYPE_PEM, crlData)
3563 self.assertTrue(isinstance(crl.get_issuer(), X509Name))
3564 self.assertEqual(crl.get_issuer().CN, 'Testing Root CA')
3565
Dominic Chenf05b2122015-10-13 16:32:35 +00003566 def test_dump_crl(self):
3567 """
3568 The dumped CRL matches the original input.
3569 """
3570 crl = load_crl(FILETYPE_PEM, crlData)
3571 buf = dump_crl(FILETYPE_PEM, crl)
3572 assert buf == crlData
3573
Dan Sully44e767a2016-06-04 18:05:27 -07003574 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3575 """
3576 Create a CRL.
3577
3578 :param list[X509] certs: A list of certificates to revoke.
3579 :rtype: CRL
3580 """
3581 crl = CRL()
3582 for cert in certs:
3583 revoked = Revoked()
3584 # FIXME: This string splicing is an unfortunate implementation
3585 # detail that has been reported in
3586 # https://github.com/pyca/pyopenssl/issues/258
3587 serial = hex(cert.get_serial_number())[2:].encode('utf-8')
3588 revoked.set_serial(serial)
3589 revoked.set_reason(b'unspecified')
3590 revoked.set_rev_date(b'20140601000000Z')
3591 crl.add_revoked(revoked)
3592 crl.set_version(1)
3593 crl.set_lastUpdate(b'20140601000000Z')
3594 crl.set_nextUpdate(b'20180601000000Z')
3595 crl.sign(issuer_cert, issuer_key, digest=b'sha512')
3596 return crl
3597
3598 def test_verify_with_revoked(self):
3599 """
3600 :func:`verify_certificate` raises error when an intermediate
3601 certificate is revoked.
3602 """
3603 store = X509Store()
3604 store.add_cert(self.root_cert)
3605 store.add_cert(self.intermediate_cert)
3606 root_crl = self._make_test_crl(
3607 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3608 intermediate_crl = self._make_test_crl(
3609 self.intermediate_cert, self.intermediate_key, certs=[])
3610 store.add_crl(root_crl)
3611 store.add_crl(intermediate_crl)
3612 store.set_flags(
3613 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3614 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3615 e = self.assertRaises(
3616 X509StoreContextError, store_ctx.verify_certificate)
3617 self.assertEqual(e.args[0][2], 'certificate revoked')
3618
3619 def test_verify_with_missing_crl(self):
3620 """
3621 :func:`verify_certificate` raises error when an intermediate
3622 certificate's CRL is missing.
3623 """
3624 store = X509Store()
3625 store.add_cert(self.root_cert)
3626 store.add_cert(self.intermediate_cert)
3627 root_crl = self._make_test_crl(
3628 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3629 store.add_crl(root_crl)
3630 store.set_flags(
3631 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3632 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3633 e = self.assertRaises(
3634 X509StoreContextError, store_ctx.verify_certificate)
3635 self.assertEqual(e.args[0][2], 'unable to get certificate CRL')
3636 self.assertEqual(
3637 e.certificate.get_subject().CN, 'intermediate-service')
3638
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003639
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003640class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003641 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003642 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003643 """
3644 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3645 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003646 intermediate_server_cert = load_certificate(
3647 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003648
3649 def test_valid(self):
3650 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003651 :py:obj:`verify_certificate` returns ``None`` when called with a
3652 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003653 """
3654 store = X509Store()
3655 store.add_cert(self.root_cert)
3656 store.add_cert(self.intermediate_cert)
3657 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003658 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003659
3660 def test_reuse(self):
3661 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003662 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003663 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003664 """
3665 store = X509Store()
3666 store.add_cert(self.root_cert)
3667 store.add_cert(self.intermediate_cert)
3668 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003669 self.assertEqual(store_ctx.verify_certificate(), None)
3670 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003671
3672 def test_trusted_self_signed(self):
3673 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003674 :py:obj:`verify_certificate` returns ``None`` when called with a
3675 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003676 """
3677 store = X509Store()
3678 store.add_cert(self.root_cert)
3679 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003680 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003681
3682 def test_untrusted_self_signed(self):
3683 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003684 :py:obj:`verify_certificate` raises error when a self-signed
3685 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003686 """
3687 store = X509Store()
3688 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003689 with pytest.raises(X509StoreContextError) as exc:
3690 store_ctx.verify_certificate()
3691
3692 assert exc.value.args[0][2] == 'self signed certificate'
3693 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003694
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003695 def test_invalid_chain_no_root(self):
3696 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003697 :py:obj:`verify_certificate` raises error when a root certificate is
3698 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003699 """
3700 store = X509Store()
3701 store.add_cert(self.intermediate_cert)
3702 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003703
3704 with pytest.raises(X509StoreContextError) as exc:
3705 store_ctx.verify_certificate()
3706
3707 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3708 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003709
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003710 def test_invalid_chain_no_intermediate(self):
3711 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003712 :py:obj:`verify_certificate` raises error when an intermediate
3713 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003714 """
3715 store = X509Store()
3716 store.add_cert(self.root_cert)
3717 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003718
Alex Gaynor85b49702015-09-05 16:30:59 -04003719 with pytest.raises(X509StoreContextError) as exc:
3720 store_ctx.verify_certificate()
3721
3722 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3723 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003724
Stephen Holsapple46a09252015-02-12 14:45:43 -08003725 def test_modification_pre_verify(self):
3726 """
3727 :py:obj:`verify_certificate` can use a store context modified after
3728 instantiation.
3729 """
3730 store_bad = X509Store()
3731 store_bad.add_cert(self.intermediate_cert)
3732 store_good = X509Store()
3733 store_good.add_cert(self.root_cert)
3734 store_good.add_cert(self.intermediate_cert)
3735 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003736
3737 with pytest.raises(X509StoreContextError) as exc:
3738 store_ctx.verify_certificate()
3739
3740 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3741 assert exc.value.certificate.get_subject().CN == 'intermediate'
3742
Stephen Holsapple46a09252015-02-12 14:45:43 -08003743 store_ctx.set_store(store_good)
3744 self.assertEqual(store_ctx.verify_certificate(), None)
3745
3746
James Yonan7c2e5d32010-02-27 05:45:50 -07003747class SignVerifyTests(TestCase):
3748 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003749 Tests for :py:obj:`OpenSSL.crypto.sign` and
3750 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003751 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003752
James Yonan7c2e5d32010-02-27 05:45:50 -07003753 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003754 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003755 :py:obj:`sign` generates a cryptographic signature which
3756 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003757 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003758 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003759 "It was a bright cold day in April, and the clocks were striking "
3760 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3761 "effort to escape the vile wind, slipped quickly through the "
3762 "glass doors of Victory Mansions, though not quickly enough to "
3763 "prevent a swirl of gritty dust from entering along with him.")
3764
3765 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003766 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003767 # verify the content with this cert
3768 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3769 # certificate unrelated to priv_key, used to trigger an error
3770 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003771
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003772 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003773 sig = sign(priv_key, content, digest)
3774
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003775 # Verify the signature of content, will throw an exception if
3776 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003777 verify(good_cert, sig, content, digest)
3778
3779 # This should fail because the certificate doesn't match the
3780 # private key that was used to sign the content.
3781 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3782
3783 # This should fail because we've "tainted" the content after
3784 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003785 self.assertRaises(
3786 Error, verify,
3787 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003788
3789 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003790 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003791 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003792 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003793 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003794
Abraham Martinc5484ba2015-03-25 15:33:05 +00003795 def test_sign_verify_with_text(self):
3796 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003797 :py:obj:`sign` generates a cryptographic signature which
3798 :py:obj:`verify` can check. Deprecation warnings raised because using
3799 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003800 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003801 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003802 b"It was a bright cold day in April, and the clocks were striking "
3803 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3804 b"effort to escape the vile wind, slipped quickly through the "
3805 b"glass doors of Victory Mansions, though not quickly enough to "
3806 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003807 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003808
3809 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3810 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3811 for digest in ['md5', 'sha1']:
3812 with catch_warnings(record=True) as w:
3813 simplefilter("always")
3814 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003815
3816 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003817 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003818 WARNING_TYPE_EXPECTED
3819 ),
3820 str(w[-1].message)
3821 )
3822 self.assertIs(w[-1].category, DeprecationWarning)
3823
Abraham Martinc5484ba2015-03-25 15:33:05 +00003824 with catch_warnings(record=True) as w:
3825 simplefilter("always")
3826 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003827
3828 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003829 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003830 WARNING_TYPE_EXPECTED
3831 ),
3832 str(w[-1].message)
3833 )
3834 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003835
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003836 def test_sign_nulls(self):
3837 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003838 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003839 """
3840 content = b("Watch out! \0 Did you see it?")
3841 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3842 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3843 sig = sign(priv_key, content, "sha1")
3844 verify(good_cert, sig, content, "sha1")
3845
Colleen Murphye09399b2016-03-01 17:40:49 -08003846 def test_sign_with_large_key(self):
3847 """
3848 :py:obj:`sign` produces a signature for a string when using a long key.
3849 """
3850 content = b(
3851 "It was a bright cold day in April, and the clocks were striking "
3852 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3853 "effort to escape the vile wind, slipped quickly through the "
3854 "glass doors of Victory Mansions, though not quickly enough to "
3855 "prevent a swirl of gritty dust from entering along with him.")
3856
3857 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3858 sign(priv_key, content, "sha1")
3859
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003860
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003861class EllipticCurveTests(TestCase):
3862 """
3863 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3864 :py:obj:`get_elliptic_curves`.
3865 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003866
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003867 def test_set(self):
3868 """
3869 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3870 """
3871 self.assertIsInstance(get_elliptic_curves(), set)
3872
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003873 def test_some_curves(self):
3874 """
3875 If :py:mod:`cryptography` has elliptic curve support then the set
3876 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3877 it.
3878
3879 There could be an OpenSSL that violates this assumption. If so, this
3880 test will fail and we'll find out.
3881 """
3882 curves = get_elliptic_curves()
3883 if lib.Cryptography_HAS_EC:
3884 self.assertTrue(curves)
3885 else:
3886 self.assertFalse(curves)
3887
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003888 def test_a_curve(self):
3889 """
3890 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3891 supported curve.
3892 """
3893 curves = get_elliptic_curves()
3894 if curves:
3895 curve = next(iter(curves))
3896 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3897 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003898 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003899
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003900 def test_not_a_curve(self):
3901 """
3902 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3903 with a name which does not identify a supported curve.
3904 """
3905 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003906 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003907
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003908 def test_repr(self):
3909 """
3910 The string representation of a curve object includes simply states the
3911 object is a curve and what its name is.
3912 """
3913 curves = get_elliptic_curves()
3914 if curves:
3915 curve = next(iter(curves))
3916 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3917
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003918 def test_to_EC_KEY(self):
3919 """
3920 The curve object can export a version of itself as an EC_KEY* via the
3921 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3922 """
3923 curves = get_elliptic_curves()
3924 if curves:
3925 curve = next(iter(curves))
3926 # It's not easy to assert anything about this object. However, see
3927 # leakcheck/crypto.py for a test that demonstrates it at least does
3928 # not leak memory.
3929 curve._to_EC_KEY()
3930
3931
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003932class EllipticCurveFactory(object):
3933 """
3934 A helper to get the names of two curves.
3935 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003936
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003937 def __init__(self):
3938 curves = iter(get_elliptic_curves())
3939 try:
3940 self.curve_name = next(curves).name
3941 self.another_curve_name = next(curves).name
3942 except StopIteration:
3943 self.curve_name = self.another_curve_name = None
3944
3945
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003946class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3947 """
3948 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3949 """
3950 curve_factory = EllipticCurveFactory()
3951
3952 if curve_factory.curve_name is None:
3953 skip = "There are no curves available there can be no curve objects."
3954
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003955 def anInstance(self):
3956 """
3957 Get the curve object for an arbitrary curve supported by the system.
3958 """
3959 return get_elliptic_curve(self.curve_factory.curve_name)
3960
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003961 def anotherInstance(self):
3962 """
3963 Get the curve object for an arbitrary curve supported by the system -
3964 but not the one returned by C{anInstance}.
3965 """
3966 return get_elliptic_curve(self.curve_factory.another_curve_name)
3967
3968
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003969class EllipticCurveHashTests(TestCase):
3970 """
3971 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3972 as an item in a :py:type:`dict` or :py:type:`set`).
3973 """
3974 curve_factory = EllipticCurveFactory()
3975
3976 if curve_factory.curve_name is None:
3977 skip = "There are no curves available there can be no curve objects."
3978
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003979 def test_contains(self):
3980 """
3981 The ``in`` operator reports that a :py:type:`set` containing a curve
3982 does contain that curve.
3983 """
3984 curve = get_elliptic_curve(self.curve_factory.curve_name)
3985 curves = set([curve])
3986 self.assertIn(curve, curves)
3987
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003988 def test_does_not_contain(self):
3989 """
3990 The ``in`` operator reports that a :py:type:`set` not containing a
3991 curve does not contain that curve.
3992 """
3993 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003994 curves = set([
3995 get_elliptic_curve(self.curve_factory.another_curve_name)
3996 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003997 self.assertNotIn(curve, curves)
3998
3999
Rick Dean5b7b6372009-04-01 11:34:06 -05004000if __name__ == '__main__':
4001 main()