blob: c441e153d3bccaad4b8e8592fda111ca29c10ccb [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 Calderone60432792015-04-13 12:26:07 -04008from warnings import catch_warnings, simplefilter
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04009
Alex Gaynor4b9c96a2014-08-14 09:51:48 -070010import base64
11import os
12import re
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -040013from subprocess import PIPE, Popen
Rick Dean47262da2009-07-08 16:17:17 -050014from datetime import datetime, timedelta
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050015
Alex Gaynor791212d2015-09-05 15:46:08 -040016import pytest
17
Alex Gaynorb8e38992015-09-04 08:14:04 -040018from six import u, b, binary_type
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050019
Paul Kehrer72d968b2016-07-29 15:31:04 +080020from cryptography.hazmat.backends.openssl.backend import backend
21from cryptography.hazmat.primitives import serialization
22from cryptography.hazmat.primitives.asymmetric import rsa
23
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050024from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050025from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
Alex Gaynor31287502015-09-05 16:11:27 -040026from OpenSSL.crypto import (
Dan Sully44e767a2016-06-04 18:05:27 -070027 X509Store,
28 X509StoreFlags,
29 X509StoreType,
30 X509StoreContext,
31 X509StoreContextError
Alex Gaynor31287502015-09-05 16:11:27 -040032)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070033from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -050034from OpenSSL.crypto import X509Extension, X509ExtensionType
Rick Dean5b7b6372009-04-01 11:34:06 -050035from OpenSSL.crypto import load_certificate, load_privatekey
Cory Benfield6492f7c2015-10-27 16:57:58 +090036from OpenSSL.crypto import load_publickey, dump_publickey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040037from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040038from OpenSSL.crypto import dump_certificate, load_certificate_request
39from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040040from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Jean-Paul Calderone9178ee62010-01-25 17:55:30 -050041from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000042from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040043from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040044from OpenSSL.crypto import (
45 sign, verify, get_elliptic_curve, get_elliptic_curves)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020046from OpenSSL._util import native, lib
47
48from .util import (
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040049 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
50)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040051
Alex Gaynoraceb3e22015-09-05 12:00:22 -040052
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040053def normalize_privatekey_pem(pem):
54 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
55
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040056
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050057GOOD_CIPHER = "blowfish"
58BAD_CIPHER = "zippers"
59
Anthony Alba2ce737f2015-12-04 11:04:56 +080060GOOD_DIGEST = "SHA1"
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050061BAD_DIGEST = "monkeys"
62
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040063root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050064MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
65BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
66ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
67NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
68MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
69ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
70urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
712xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
721dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
73FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
74VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
75BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
76b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
77AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
78hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
79w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
80-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040081""")
Rick Dean94e46fd2009-07-18 14:51:24 -050082
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040083root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050084MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
85jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
863claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
87AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
88yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
896JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
90BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
91u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
92PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
93I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
94ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
956AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
96cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
97-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040098""")
Rick Dean94e46fd2009-07-18 14:51:24 -050099
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700100intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
101MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
102WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
103DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
104ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
105dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
106MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
107AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
108FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
10921H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
110AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
111QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1129n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1139mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
114-----END CERTIFICATE-----
115""")
116
117intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
118MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
119ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
120qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
121AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
122rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
123147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
124+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
125wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
126sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
12752vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
128DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
129/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
130NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
131-----END RSA PRIVATE KEY-----
132""")
133
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400134server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500135MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
136BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
137VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
138NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
139gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
140lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
141b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
142lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
143gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
144dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1452mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
146uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
147-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400148""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500149
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400150server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500151MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
152U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
153SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
154AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
155j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
156j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
157Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
158msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
159FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1604e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1611sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
162NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
163r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
164-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400165"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500166
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700167intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
168MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
169ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
170CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
171biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
172BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
173CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
174biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
175iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
176+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
177biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
178UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1793bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
180x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
181-----END CERTIFICATE-----
182""")
183
184intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
185MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
186SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1878Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
188AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1895ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
190d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
191z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
192dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
193EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
194X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
1959UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
196ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
197nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
198-----END RSA PRIVATE KEY-----
199""")
200
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400201client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500202MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
203BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
204VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
205ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
206MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
207rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
208iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
209oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2100fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
211Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2129Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
213PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
214-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400215""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500216
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400217client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500218MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
219btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
220eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
221AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
222zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
223h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
224V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
225TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
226dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
227D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
228si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
229JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
230f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
231-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400232"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400233
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400234cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400235MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
236BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
237ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
238NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
239MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
240ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
241urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2422xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2431dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
244FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
245VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
246BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
247b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
248AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
249hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
250w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
251-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400252""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400253
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400254cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
255-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400256MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
257jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2583claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
259AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
260yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2616JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
262BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
263u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
264PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
265I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
266ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2676AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
268cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
269-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400270"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400271
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400272cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
273MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
274EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
275ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
276BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
277E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
278xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
279gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
280Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
281oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
282-----END CERTIFICATE REQUEST-----
283""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500284
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400285encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400286Proc-Type: 4,ENCRYPTED
287DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400288
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400289SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
290a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2918+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
292mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
293+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
294fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
295tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
296rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
297gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
298o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
2997SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
300MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
30111n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
302-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400303""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400304
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400305encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400306
Cory Benfield6492f7c2015-10-27 16:57:58 +0900307
308cleartextPublicKeyPEM = b("""-----BEGIN PUBLIC KEY-----
309MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
310gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
31190qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
312ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
313XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
3148Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
315ywIDAQAB
316-----END PUBLIC KEY-----
317""")
318
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400319# Some PKCS#7 stuff. Generated with the openssl command line:
320#
321# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
322#
323# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400324pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400325-----BEGIN PKCS7-----
326MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
327BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
328A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
329MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
330cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
331A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
332HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
333SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
334zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
335LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
336A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
33765w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
338Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
339Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
340bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
341VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
342/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
343Ho4EzbYCOaEAMQA=
344-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400345""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400346
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700347pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700348MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
349BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
350A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
351MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
352cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
353A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
354HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
355SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
356zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
357LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
358A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
35965w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
360Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
361Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
362bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
363VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
364/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
365Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700366""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700367
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400368crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500369-----BEGIN X509 CRL-----
370MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
371SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
372D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
373MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
374MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3754dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3760yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
377vrzEeLDRiiPl92dyyWmu
378-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400379""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400380
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400381crlDataUnsupportedExtension = b("""\
382-----BEGIN X509 CRL-----
383MIIGRzCCBS8CAQIwDQYJKoZIhvcNAQELBQAwJzELMAkGA1UEBhMCVVMxGDAWBgNV
384BAMMD2NyeXB0b2dyYXBoeS5pbxgPMjAxNTAxMDEwMDAwMDBaGA8yMDE2MDEwMTAw
385MDAwMFowggTOMBQCAQAYDzIwMTUwMTAxMDAwMDAwWjByAgEBGA8yMDE1MDEwMTAw
386MDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAn
387MQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQD
388CgEAMHICAQIYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAw
389MDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlw
390dG9ncmFwaHkuaW8wCgYDVR0VBAMKAQEwcgIBAxgPMjAxNTAxMDEwMDAwMDBaMFww
391GAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTArpCkwJzELMAkGA1UE
392BhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNVHRUEAwoBAjByAgEE
393GA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAxMDEwMDAwMDBaMDQG
394A1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5
395LmlvMAoGA1UdFQQDCgEDMHICAQUYDzIwMTUwMTAxMDAwMDAwWjBcMBgGA1UdGAQR
396GA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJBgNVBAYTAlVTMRgw
397FgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQQwcgIBBhgPMjAxNTAx
398MDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAwWjA0BgNVHR0ELTAr
399pCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pbzAKBgNV
400HRUEAwoBBTByAgEHGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNVHRgEERgPMjAxNTAx
401MDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJVUzEYMBYGA1UEAwwP
402Y3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEGMHICAQgYDzIwMTUwMTAxMDAwMDAw
403WjBcMBgGA1UdGAQRGA8yMDE1MDEwMTAwMDAwMFowNAYDVR0dBC0wK6QpMCcxCzAJ
404BgNVBAYTAlVTMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wCgYDVR0VBAMKAQgw
405cgIBCRgPMjAxNTAxMDEwMDAwMDBaMFwwGAYDVR0YBBEYDzIwMTUwMTAxMDAwMDAw
406WjA0BgNVHR0ELTArpCkwJzELMAkGA1UEBhMCVVMxGDAWBgNVBAMMD2NyeXB0b2dy
407YXBoeS5pbzAKBgNVHRUEAwoBCTByAgEKGA8yMDE1MDEwMTAwMDAwMFowXDAYBgNV
408HRgEERgPMjAxNTAxMDEwMDAwMDBaMDQGA1UdHQQtMCukKTAnMQswCQYDVQQGEwJV
409UzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMAoGA1UdFQQDCgEKMC4CAQsYDzIw
410MTUwMTAxMDAwMDAwWjAYMAoGA1UdFQQDCgEBMAoGAyoDBAQDCgEAMA0GCSqGSIb3
411DQEBCwUAA4IBAQBTaloHlPaCZzYee8LxkWej5meiqxQVNWFoVdjesroa+f1FRrH+
412drRU60Nq97KCKf7f9GNN/J3ZIlQmYhmuDqh12f+XLpotoj1ZRfBz2hjFCkJlv+2c
413oWWGNHgA70ndFoVtcmX088SYpX8E3ARATivS4q2h9WlwV6rO93mhg3HGIe3JpcK4
4147BcW6Poi/ut/zsDOkVbI00SqaujRpdmdCTht82MH3ztjyDkI9KYaD/YEweKSrWOz
415SdEILd164bfBeLuplVI+xpmTEMVNpXBlSXl7+xIw9Vk7p7Q1Pa3k/SvhOldYCm6y
416C1xAg/AAq6w78yzYt18j5Mj0s6eeHi1YpHKw
417-----END X509 CRL-----
418""")
419
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400420
421# A broken RSA private key which can be used to test the error path through
422# PKey.check.
423inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
424MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
4255kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
426OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
427zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
428nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
429HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
430oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
431-----END RSA PRIVATE KEY-----
432""")
433
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400434# certificate with NULL bytes in subjectAltName and common name
435
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400436nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400437MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
438DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
439eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
440RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
441ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
442NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
443DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
444ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
445ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
446hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
447BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
448pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
449vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
450KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
451oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
45208LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
453HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
454BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
455Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
456bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
457AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
458i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
459HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
460kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
461VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
462RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
463-----END CERTIFICATE-----""")
464
Colleen Murphye09399b2016-03-01 17:40:49 -0800465large_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
466MIIJYgIBAAKCAg4AtRua8eIeevRfsj+fkcHr1vmse7Kgb+oX1ssJAvCb1R7JQMnH
467hNDjDP6b3vEkZuPUzlDHymP+cNkXvvi4wJ4miVbO3+SeU4Sh+jmsHeHzGIXat9xW
4689PFtuPM5FQq8zvkY8aDeRYmYwN9JKu4/neMBCBqostYlTEWg+bSytO/qWnyHTHKh
469g0GfaDdqUQPsGQw+J0MgaYIjQOCVASHAPlzbDQLCtuOb587rwTLkZA2GwoHB/LyJ
470BwT0HHgBaiObE12Vs6wi2en0Uu11CiwEuK1KIBcZ2XbE6eApaZa6VH9ysEmUxPt7
471TqyZ4E2oMIYaLPNRxuvozdwTlj1svI1k1FrkaXGc5MTjbgigPMKjIb0T7b/4GNzt
472DhP1LvAeUMnrEi3hJJrcJPXHPqS8/RiytR9xQQW6Sdh4LaA3f9MQm3WSevWage3G
473P8YcCLssOVKsArDjuA52NF5LmYuAeUzXprm4ITDi2oO+0iFBpFW6VPEK4A9vO0Yk
474M/6Wt6tG8zyWhaSH1zFUTwfQ9Yvjyt5w1lrUaAJuoTpwbMVZaDJaEhjOaXU0dyPQ
475jOsePDOQcU6dkeTWsQ3LsHPEEug/X6819TLG5mb3V7bvV9nPFBfTJSCEG794kr90
476XgZfIN71FrdByxLerlbuJI21pPs/nZi9SXi9jAWeiS45/azUxMsyYgJArui+gjq7
477sV1pWiBm6/orAgMBAAECggINQp5L6Yu+oIXBqcSjgq8tfF9M5hd30pLuf/EheHZf
478LA7uAqn2fVGFI2OInIJhXIOT5OxsAXO0xXfltzawZxIFpOFMqajj4F7aYjvSpw9V
479J4EdSiJ/zgv8y1qUdbwEZbHVThRZjoSlrtSzilonBoHZAE0mHtqMz7iRFSk1zz6t
480GunRrvo/lROPentf3TsvHquVNUYI5yaapyO1S7xJhecMIIYSb8nbsHI54FBDGNas
4816mFmpPwI/47/6HTwOEWupnn3NicsjrHzUInOUpaMig4cRR+aP5bjqg/ty8xI8AoN
482evEmCytiWTc+Rvbp1ieN+1jpjN18PjUk80/W7qioHUDt4ieLic8uxWH2VD9SCEnX
483Mpi9tA/FqoZ+2A/3m1OfrY6jiZVE2g+asi9lCK7QVWL39eK82H4rPvtp0/dyo1/i
484ZZz68TXg+m8IgEZcp88hngbkuoTTzpGE73QuPKhGA1uMIimDdqPPB5WP76q+03Oi
485IRR5DfZnqPERed49by0enJ7tKa/gFPZizOV8ALKr0Dp+vfAkxGDLPLBLd2A3//tw
486xg0Q/wltihHSBujv4nYlDXdc5oYyMYZ+Lhc/VuOghHfBq3tgEQ1ECM/ofqXEIdy7
487nVcpZn3Eeq8Jl5CrqxE1ee3NxlzsJHn99yGQpr7mOhW/psJF3XNz80Meg3L4m1T8
488sMBK0GbaassuJhdzb5whAoIBBw48sx1b1WR4XxQc5O/HjHva+l16i2pjUnOUTcDF
489RWmSbIhBm2QQ2rVhO8+fak0tkl6ZnMWW4i0U/X5LOEBbC7+IS8bO3j3Revi+Vw5x
490j96LMlIe9XEub5i/saEWgiz7maCvfzLFU08e1OpT4qPDpP293V400ubA6R7WQTCv
491pBkskGwHeu0l/TuKkVqBFFUTu7KEbps8Gjg7MkJaFriAOv1zis/umK8pVS3ZAM6e
4928w5jfpRccn8Xzta2fRwTB5kCmfxdDsY0oYGxPLRAbW72bORoLGuyyPp/ojeGwoik
493JX9RttErc6FjyZtks370Pa8UL5QskyhMbDhrZW2jFD+RXYM1BrvmZRjbAoIBBwy4
494iFJpuDfytJfz1MWtaL5DqEL/kmiZYAXl6hifNhGu5GAipVIIGsDqEYW4i+VC15aa
4957kOCwz/I5zsB3vSDW96IRs4wXtqEZSibc2W/bqfVi+xcvPPl1ZhQ2EAwa4D/x035
496kyf20ffWOU+1yf2cnijzqs3IzlveUm+meLw5s3Rc+iG7DPWWeCoe1hVwANI1euNc
497pqKwKY905yFyjOje2OgiEU2kS4YME4zGeBys8yo7E42hNnN2EPK6xkkUqzdudLLQ
4988OUlKRTc8AbIf3XG1rpA4VUpTv3hhxGGwCRy6If8zgZQsNYchgNztRGk72Gcb8Dm
499vFSEN3ZtwxU64G3YZzntdcr2WPzxAoIBBw30g6Fgdb/gmVnOpL0//T0ePNDKIMPs
500jVJLaRduhoZgB1Bb9qPUPX0SzRzLZtg1tkZSDjBDoHmOHJfhxUaXt+FLCPPbrE4t
501+nq9n/nBaMM779w9ClqhqLOyGrwKoxjSmhi+TVEHyIxCbXMvPHVHfX9WzxjbcGrN
502ZvRaEVZWo+QlIX8yqdSwqxLk1WtAIRzvlcj7NKum8xBxPed6BNFep/PtgIAmoLT5
503L8wb7EWb2iUdc2KbZ4OaY51lDScqpATgXu3WjXfM+Q52G0mX6Wyd0cjlL711Zrjb
504yLbiueZT94lgIHHRRKtKc8CEqcjkQV5OzABS3P/gQSfgZXBdLKjOpTnKDUq7IBeH
505AoIBBweAOEIAPLQg1QRUrr3xRrYKRwlakgZDii9wJt1l5AgBTICzbTA1vzDJ1JM5
506AqSpCV6w9JWyYVcXK+HLdKBRZLaPPNEQDJ5lOxD6uMziWGl2rg8tj+1xNMWfxiPz
507aTCjoe4EoBUMoTq2gwzRcM2usEQNikXVhnj9Wzaivsaeb4bJ3GRPW5DkrO6JSEtT
508w+gvyMqQM2Hy5k7E7BT46sXVwaj/jZxuqGnebRixXtnp0WixdRIqYWUr1UqLf6hQ
509G7WP2BgoxCMaCmNW8+HMD/xuxucEotoIhZ+GgJKBFoNnjl3BX+qxYdSe9RbL/5Tr
5104It6Jxtj8uETJXEbv9Cg6v1agWPS9YY8RLTBAoIBBwrU2AsAUts6h1LgGLKK3UWZ
511oLH5E+4o+7HqSGRcRodVeN9NBXIYdHHOLeEG6YNGJiJ3bFP5ZQEu9iDsyoFVKJ9O
512Mw/y6dKZuxOCZ+X8FopSROg3yWfdOpAm6cnQZp3WqLNX4n/Q6WvKojfyEiPphjwT
5130ymrUJELXLWJmjUyPoAk6HgC0Gs28ZnEXbyhx7CSbZNFyCU/PNUDZwto3GisIPD3
514le7YjqHugezmjMGlA0sDw5aCXjfbl74vowRFYMO6e3ItApfSRgNV86CDoX74WI/5
515AYU/QVM4wGt8XGT2KwDFJaxYGKsGDMWmXY04dS+WPuetCbouWUusyFwRb9SzFave
516vYeU7Ab/
517-----END RSA PRIVATE KEY-----""")
518
Paul Kehrer72d968b2016-07-29 15:31:04 +0800519ec_private_key_pem = b"""-----BEGIN PRIVATE KEY-----
520MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgYirTZSx+5O8Y6tlG
521cka6W6btJiocdrdolfcukSoTEk+hRANCAAQkvPNu7Pa1GcsWU4v7ptNfqCJVq8Cx
522zo0MUVPQgwJ3aJtNM1QMOQUayCrRwfklg+D/rFSUwEUqtZh7fJDiFqz3
523-----END PRIVATE KEY-----
524"""
525
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400526
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400527class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400528 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900529 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400530 """
531
532 def setUp(self):
533 """
534 Create a new private key and start a certificate request (for a test
535 method to finish in one way or another).
536 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800537 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400538 # Basic setup stuff to generate a certificate
539 self.pkey = PKey()
540 self.pkey.generate_key(TYPE_RSA, 384)
541 self.req = X509Req()
542 self.req.set_pubkey(self.pkey)
543 # Authority good you have.
544 self.req.get_subject().commonName = "Yoda root CA"
545 self.x509 = X509()
546 self.subject = self.x509.get_subject()
547 self.subject.commonName = self.req.get_subject().commonName
548 self.x509.set_issuer(self.subject)
549 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400550 now = datetime.now()
551 expire = datetime.now() + timedelta(days=100)
552 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
553 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400554
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800555 def tearDown(self):
556 """
557 Forget all of the pyOpenSSL objects so they can be garbage collected,
558 their memory released, and not interfere with the leak detection code.
559 """
560 self.pkey = self.req = self.x509 = self.subject = None
561 super(X509ExtTests, self).tearDown()
562
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400563 def test_str(self):
564 """
Alex Gaynor31287502015-09-05 16:11:27 -0400565 The string representation of :py:class:`X509Extension` instances as
566 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400567 """
568 # This isn't necessarily the best string representation. Perhaps it
569 # will be changed/improved in the future.
570 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400571 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400572 'CA:FALSE')
573
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400574 def test_type(self):
575 """
Alex Gaynor31287502015-09-05 16:11:27 -0400576 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
577 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400578 """
579 self.assertIdentical(X509Extension, X509ExtensionType)
580 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400581 X509Extension,
582 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400583
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500584 def test_construction(self):
585 """
Alex Gaynor31287502015-09-05 16:11:27 -0400586 :py:class:`X509Extension` accepts an extension type name, a critical
587 flag, and an extension value and returns an
588 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500589 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400590 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500591 self.assertTrue(
592 isinstance(basic, X509ExtensionType),
593 "%r is of type %r, should be %r" % (
594 basic, type(basic), X509ExtensionType))
595
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400596 comment = X509Extension(
597 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500598 self.assertTrue(
599 isinstance(comment, X509ExtensionType),
600 "%r is of type %r, should be %r" % (
601 comment, type(comment), X509ExtensionType))
602
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500603 def test_invalid_extension(self):
604 """
Alex Gaynor31287502015-09-05 16:11:27 -0400605 :py:class:`X509Extension` raises something if it is passed a bad
606 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500607 """
608 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400609 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500610 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400611 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500612
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500613 # Exercise a weird one (an extension which uses the r2i method). This
614 # exercises the codepath that requires a non-NULL ctx to be passed to
615 # X509V3_EXT_nconf. It can't work now because we provide no
616 # configuration database. It might be made to work in the future.
617 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400618 Error, X509Extension, b('proxyCertInfo'), True,
619 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500620
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500621 def test_get_critical(self):
622 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900623 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500624 extension's critical flag.
625 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400626 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500627 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400628 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500629 self.assertFalse(ext.get_critical())
630
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500631 def test_get_short_name(self):
632 """
Alex Gaynor31287502015-09-05 16:11:27 -0400633 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
634 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500635 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400636 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
637 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
638 ext = X509Extension(b('nsComment'), True, b('foo bar'))
639 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500640
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400641 def test_get_data(self):
642 """
Alex Gaynor31287502015-09-05 16:11:27 -0400643 :py:meth:`X509Extension.get_data` returns a string giving the data of
644 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400645 """
646 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
647 # Expect to get back the DER encoded form of CA:true.
648 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
649
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400650 def test_get_data_wrong_args(self):
651 """
Alex Gaynor31287502015-09-05 16:11:27 -0400652 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
653 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400654 """
655 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
656 self.assertRaises(TypeError, ext.get_data, None)
657 self.assertRaises(TypeError, ext.get_data, "foo")
658 self.assertRaises(TypeError, ext.get_data, 7)
659
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400660 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500661 """
Alex Gaynor31287502015-09-05 16:11:27 -0400662 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
663 provided for an extension which does not use it and is ignored in this
664 case.
Rick Dean47262da2009-07-08 16:17:17 -0500665 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400666 ext1 = X509Extension(
667 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400668 self.x509.add_extensions([ext1])
669 self.x509.sign(self.pkey, 'sha1')
670 # This is a little lame. Can we think of a better way?
671 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400672 self.assertTrue(b('X509v3 Basic Constraints:') in text)
673 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400674
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400675 def test_subject(self):
676 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900677 If an extension requires a subject, the :py:data:`subject` parameter to
678 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400679 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400680 ext3 = X509Extension(
681 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400682 self.x509.add_extensions([ext3])
683 self.x509.sign(self.pkey, 'sha1')
684 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400685 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400686
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400687 def test_missing_subject(self):
688 """
Alex Gaynor31287502015-09-05 16:11:27 -0400689 If an extension requires a subject and the :py:data:`subject` parameter
690 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400691 """
692 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400693 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400694
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400695 def test_invalid_subject(self):
696 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900697 If the :py:data:`subject` parameter is given a value which is not an
698 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400699 """
700 for badObj in [True, object(), "hello", [], self]:
701 self.assertRaises(
702 TypeError,
703 X509Extension,
704 'basicConstraints', False, 'CA:TRUE', subject=badObj)
705
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400706 def test_unused_issuer(self):
707 """
Alex Gaynor31287502015-09-05 16:11:27 -0400708 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
709 provided for an extension which does not use it and is ignored in this
710 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400711 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400712 ext1 = X509Extension(
713 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400714 self.x509.add_extensions([ext1])
715 self.x509.sign(self.pkey, 'sha1')
716 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400717 self.assertTrue(b('X509v3 Basic Constraints:') in text)
718 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400719
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400720 def test_issuer(self):
721 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800722 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900723 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400724 """
725 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400726 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400727 issuer=self.x509)
728 self.x509.add_extensions([ext2])
729 self.x509.sign(self.pkey, 'sha1')
730 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400731 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
732 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400733
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400734 def test_missing_issuer(self):
735 """
Alex Gaynor31287502015-09-05 16:11:27 -0400736 If an extension requires an issue and the :py:data:`issuer` parameter
737 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400738 """
739 self.assertRaises(
740 Error,
741 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400742 b('authorityKeyIdentifier'), False,
743 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400744
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400745 def test_invalid_issuer(self):
746 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900747 If the :py:data:`issuer` parameter is given a value which is not an
748 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400749 """
750 for badObj in [True, object(), "hello", [], self]:
751 self.assertRaises(
752 TypeError,
753 X509Extension,
754 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
755 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500756
757
Paul Kehrer72d968b2016-07-29 15:31:04 +0800758class TestPKey(object):
759 """
760 py.test-based tests for :class:`OpenSSL.crypto.PKey`.
761
762 If possible, add new tests here.
763 """
764
765 def test_convert_from_cryptography_private_key(self):
766 """
767 PKey.from_cryptography_key creates a proper private PKey.
768 """
769 key = serialization.load_pem_private_key(
770 intermediate_key_pem, None, backend
771 )
772 pkey = PKey.from_cryptography_key(key)
773
774 assert isinstance(pkey, PKey)
775 assert pkey.bits() == key.key_size
776 assert pkey._only_public is False
777 assert pkey._initialized is True
778
779 def test_convert_from_cryptography_public_key(self):
780 """
781 PKey.from_cryptography_key creates a proper public PKey.
782 """
783 key = serialization.load_pem_public_key(cleartextPublicKeyPEM, backend)
784 pkey = PKey.from_cryptography_key(key)
785
786 assert isinstance(pkey, PKey)
787 assert pkey.bits() == key.key_size
788 assert pkey._only_public is True
789 assert pkey._initialized is True
790
791 def test_convert_from_cryptography_unsupported_type(self):
792 """
793 PKey.from_cryptography_key raises TypeError with an unsupported type.
794 """
795 key = serialization.load_pem_private_key(
796 ec_private_key_pem, None, backend
797 )
798 with pytest.raises(TypeError):
799 PKey.from_cryptography_key(key)
800
801 def test_convert_public_pkey_to_cryptography_key(self):
802 """
803 PKey.to_cryptography_key creates a proper cryptography public key.
804 """
805 pkey = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
806 key = pkey.to_cryptography_key()
807
808 assert isinstance(key, rsa.RSAPublicKey)
809 assert pkey.bits() == key.key_size
810
811 def test_convert_private_pkey_to_cryptography_key(self):
812 """
813 PKey.to_cryptography_key creates a proper cryptography private key.
814 """
815 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
816 key = pkey.to_cryptography_key()
817
818 assert isinstance(key, rsa.RSAPrivateKey)
819 assert pkey.bits() == key.key_size
820
821
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400822class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500823 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900824 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500825 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400826
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400827 def test_type(self):
828 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900829 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
830 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400831 """
832 self.assertIdentical(PKey, PKeyType)
833 self.assertConsistentType(PKey, 'PKey')
834
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500835 def test_construction(self):
836 """
Alex Gaynor31287502015-09-05 16:11:27 -0400837 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
838 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500839 """
840 self.assertRaises(TypeError, PKey, None)
841 key = PKey()
842 self.assertTrue(
843 isinstance(key, PKeyType),
844 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
845
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500846 def test_pregeneration(self):
847 """
Alex Gaynor31287502015-09-05 16:11:27 -0400848 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
849 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
850 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500851 """
852 key = PKey()
853 self.assertEqual(key.type(), 0)
854 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400855 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500856
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500857 def test_failedGeneration(self):
858 """
Alex Gaynor31287502015-09-05 16:11:27 -0400859 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
860 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
861 the second giving the number of bits to generate. If an invalid type
862 is specified or generation fails, :py:exc:`Error` is raised. If an
863 invalid number of bits is specified, :py:exc:`ValueError` or
864 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500865 """
866 key = PKey()
867 self.assertRaises(TypeError, key.generate_key)
868 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
869 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
870 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500871
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500872 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
873 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500874
Alex Gaynor5bb2bd12016-07-03 10:48:32 -0400875 with pytest.raises(TypeError):
876 key.generate_key(TYPE_RSA, object())
877
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500878 # XXX RSA generation for small values of bits is fairly buggy in a wide
879 # range of OpenSSL versions. I need to figure out what the safe lower
880 # bound for a reasonable number of OpenSSL versions is and explicitly
881 # check for that in the wrapper. The failure behavior is typically an
882 # infinite loop inside OpenSSL.
883
884 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500885
886 # XXX DSA generation seems happy with any number of bits. The DSS
887 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
888 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500889 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500890 # So, it doesn't seem possible to make generate_key fail for
891 # TYPE_DSA with a bits argument which is at least an int.
892
893 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
894
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500895 def test_rsaGeneration(self):
896 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900897 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
898 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500899 """
900 bits = 128
901 key = PKey()
902 key.generate_key(TYPE_RSA, bits)
903 self.assertEqual(key.type(), TYPE_RSA)
904 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400905 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500906
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500907 def test_dsaGeneration(self):
908 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900909 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
910 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500911 """
912 # 512 is a magic number. The DSS (Digital Signature Standard)
913 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
914 # will silently promote any value below 512 to 512.
915 bits = 512
916 key = PKey()
917 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800918 # self.assertEqual(key.type(), TYPE_DSA)
919 # self.assertEqual(key.bits(), bits)
920 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500921
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500922 def test_regeneration(self):
923 """
Alex Gaynor31287502015-09-05 16:11:27 -0400924 :py:meth:`PKeyType.generate_key` can be called multiple times on the
925 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500926 """
927 key = PKey()
928 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400929 key.generate_key(type, bits)
930 self.assertEqual(key.type(), type)
931 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500932
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400933 def test_inconsistentKey(self):
934 """
Alex Gaynor31287502015-09-05 16:11:27 -0400935 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
936 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400937 """
938 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400939 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400940
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400941 def test_check_wrong_args(self):
942 """
Alex Gaynor31287502015-09-05 16:11:27 -0400943 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
944 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400945 """
946 self.assertRaises(TypeError, PKey().check, None)
947 self.assertRaises(TypeError, PKey().check, object())
948 self.assertRaises(TypeError, PKey().check, 1)
949
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400950 def test_check_public_key(self):
951 """
952 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
953 part of the key is available.
954 """
955 # A trick to get a public-only key
956 key = PKey()
957 key.generate_key(TYPE_RSA, 512)
958 cert = X509()
959 cert.set_pubkey(key)
960 pub = cert.get_pubkey()
961 self.assertRaises(TypeError, pub.check)
962
963
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400964class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500965 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900966 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500967 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400968
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500969 def _x509name(self, **attrs):
970 # XXX There's no other way to get a new X509Name yet.
971 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400972 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400973
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500974 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400975 def key(attr):
976 return attr[1]
977 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500978 for k, v in attrs:
979 setattr(name, k, v)
980 return name
981
Rick Deane15b1472009-07-09 15:53:42 -0500982 def test_type(self):
983 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900984 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500985 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400986 self.assertIdentical(X509Name, X509NameType)
987 self.assertEqual(X509NameType.__name__, 'X509Name')
988 self.assertTrue(isinstance(X509NameType, type))
989
Rick Deane15b1472009-07-09 15:53:42 -0500990 name = self._x509name()
991 self.assertTrue(
992 isinstance(name, X509NameType),
993 "%r is of type %r, should be %r" % (
994 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500995
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400996 def test_onlyStringAttributes(self):
997 """
Alex Gaynor31287502015-09-05 16:11:27 -0400998 Attempting to set a non-:py:data:`str` attribute name on an
999 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
1000 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001001 """
1002 name = self._x509name()
1003 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -04001004 # rejected. Sorry, you're wrong. unicode is automatically converted
1005 # to str outside of the control of X509Name, so there's no way to
1006 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -08001007
Alex Gaynor31287502015-09-05 16:11:27 -04001008 # Also, this used to test str subclasses, but that test is less
1009 # relevant now that the implementation is in Python instead of C. Also
1010 # PyPy automatically converts str subclasses to str when they are
1011 # passed to setattr, so we can't test it on PyPy. Apparently CPython
1012 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001013 self.assertRaises(TypeError, setattr, name, None, "hello")
1014 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001015
1016 def test_setInvalidAttribute(self):
1017 """
Alex Gaynor31287502015-09-05 16:11:27 -04001018 Attempting to set any attribute name on an :py:class:`X509NameType`
1019 instance for which no corresponding NID is defined causes
1020 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001021 """
1022 name = self._x509name()
1023 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
1024
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001025 def test_attributes(self):
1026 """
Alex Gaynor31287502015-09-05 16:11:27 -04001027 :py:class:`X509NameType` instances have attributes for each standard
1028 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001029 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001030 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001031 name.commonName = "foo"
Alex Gaynor37726112016-07-04 09:51:32 -04001032 assert name.commonName == "foo"
1033 assert name.CN == "foo"
1034
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001035 name.CN = "baz"
Alex Gaynor37726112016-07-04 09:51:32 -04001036 assert name.commonName == "baz"
1037 assert name.CN == "baz"
1038
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001039 name.commonName = "bar"
Alex Gaynor37726112016-07-04 09:51:32 -04001040 assert name.commonName == "bar"
1041 assert name.CN == "bar"
1042
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001043 name.CN = "quux"
Alex Gaynor37726112016-07-04 09:51:32 -04001044 assert name.commonName == "quux"
1045 assert name.CN == "quux"
1046
1047 assert name.OU is None
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001048
Alex Gaynor7778e792016-07-03 23:38:48 -04001049 with pytest.raises(AttributeError):
1050 name.foobar
1051
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001052 def test_copy(self):
1053 """
Alex Gaynor31287502015-09-05 16:11:27 -04001054 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
1055 with all the same attributes as an existing :py:class:`X509NameType`
1056 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001057 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001058 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001059
1060 copy = X509Name(name)
1061 self.assertEqual(copy.commonName, "foo")
1062 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001063
1064 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001065 copy.commonName = "baz"
1066 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001067
1068 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001069 name.emailAddress = "quux@example.com"
1070 self.assertEqual(copy.emailAddress, "bar@example.com")
1071
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001072 def test_repr(self):
1073 """
Alex Gaynor31287502015-09-05 16:11:27 -04001074 :py:func:`repr` passed an :py:class:`X509NameType` instance should
1075 return a string containing a description of the type and the NIDs which
1076 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001077 """
1078 name = self._x509name(commonName="foo", emailAddress="bar")
1079 self.assertEqual(
1080 repr(name),
1081 "<X509Name object '/emailAddress=bar/CN=foo'>")
1082
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001083 def test_comparison(self):
1084 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001085 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001086 """
1087 def _equality(a, b, assertTrue, assertFalse):
1088 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
1089 assertFalse(a != b)
1090 assertTrue(b == a)
1091 assertFalse(b != a)
1092
1093 def assertEqual(a, b):
1094 _equality(a, b, self.assertTrue, self.assertFalse)
1095
1096 # Instances compare equal to themselves.
1097 name = self._x509name()
1098 assertEqual(name, name)
1099
1100 # Empty instances should compare equal to each other.
1101 assertEqual(self._x509name(), self._x509name())
1102
1103 # Instances with equal NIDs should compare equal to each other.
1104 assertEqual(self._x509name(commonName="foo"),
1105 self._x509name(commonName="foo"))
1106
1107 # Instance with equal NIDs set using different aliases should compare
1108 # equal to each other.
1109 assertEqual(self._x509name(commonName="foo"),
1110 self._x509name(CN="foo"))
1111
1112 # Instances with more than one NID with the same values should compare
1113 # equal to each other.
1114 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
1115 self._x509name(commonName="foo", OU="bar"))
1116
1117 def assertNotEqual(a, b):
1118 _equality(a, b, self.assertFalse, self.assertTrue)
1119
1120 # Instances with different values for the same NID should not compare
1121 # equal to each other.
1122 assertNotEqual(self._x509name(CN="foo"),
1123 self._x509name(CN="bar"))
1124
1125 # Instances with different NIDs should not compare equal to each other.
1126 assertNotEqual(self._x509name(CN="foo"),
1127 self._x509name(OU="foo"))
1128
Alex Gaynor7778e792016-07-03 23:38:48 -04001129 assertNotEqual(self._x509name(), object())
1130
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001131 def _inequality(a, b, assertTrue, assertFalse):
1132 assertTrue(a < b)
1133 assertTrue(a <= b)
1134 assertTrue(b > a)
1135 assertTrue(b >= a)
1136 assertFalse(a > b)
1137 assertFalse(a >= b)
1138 assertFalse(b < a)
1139 assertFalse(b <= a)
1140
1141 def assertLessThan(a, b):
1142 _inequality(a, b, self.assertTrue, self.assertFalse)
1143
1144 # An X509Name with a NID with a value which sorts less than the value
1145 # of the same NID on another X509Name compares less than the other
1146 # X509Name.
1147 assertLessThan(self._x509name(CN="abc"),
1148 self._x509name(CN="def"))
1149
1150 def assertGreaterThan(a, b):
1151 _inequality(a, b, self.assertFalse, self.assertTrue)
1152
1153 # An X509Name with a NID with a value which sorts greater than the
1154 # value of the same NID on another X509Name compares greater than the
1155 # other X509Name.
1156 assertGreaterThan(self._x509name(CN="def"),
1157 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001158
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001159 def test_hash(self):
1160 """
Alex Gaynor31287502015-09-05 16:11:27 -04001161 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1162 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001163 """
1164 a = self._x509name(CN="foo")
1165 b = self._x509name(CN="foo")
1166 self.assertEqual(a.hash(), b.hash())
1167 a.CN = "bar"
1168 self.assertNotEqual(a.hash(), b.hash())
1169
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001170 def test_der(self):
1171 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001172 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001173 """
1174 a = self._x509name(CN="foo", C="US")
1175 self.assertEqual(
1176 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001177 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001178 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001179
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001180 def test_get_components(self):
1181 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001182 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1183 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001184 giving the NIDs and associated values which make up the name.
1185 """
1186 a = self._x509name()
1187 self.assertEqual(a.get_components(), [])
1188 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001189 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001190 a.organizationalUnitName = "bar"
1191 self.assertEqual(
1192 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001193 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001194
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001195 def test_load_nul_byte_attribute(self):
1196 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001197 An :py:class:`OpenSSL.crypto.X509Name` from an
1198 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001199 NUL byte in the value of one of its attributes.
1200 """
1201 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1202 subject = cert.get_subject()
1203 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001204 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001205
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001206 def test_setAttributeFailure(self):
1207 """
1208 If the value of an attribute cannot be set for some reason then
1209 :py:class:`OpenSSL.crypto.Error` is raised.
1210 """
1211 name = self._x509name()
1212 # This value is too long
1213 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1214
1215
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001216class _PKeyInteractionTestsMixin:
1217 """
1218 Tests which involve another thing and a PKey.
1219 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001220
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001221 def signable(self):
1222 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001223 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1224 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001225 """
1226 raise NotImplementedError()
1227
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001228 def test_signWithUngenerated(self):
1229 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001230 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1231 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001232 """
1233 request = self.signable()
1234 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001235 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001236
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001237 def test_signWithPublicKey(self):
1238 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001239 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1240 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001241 """
1242 request = self.signable()
1243 key = PKey()
1244 key.generate_key(TYPE_RSA, 512)
1245 request.set_pubkey(key)
1246 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001247 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001248
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001249 def test_signWithUnknownDigest(self):
1250 """
Alex Gaynor31287502015-09-05 16:11:27 -04001251 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1252 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001253 """
1254 request = self.signable()
1255 key = PKey()
1256 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001257 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001258
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001259 def test_sign(self):
1260 """
Alex Gaynor31287502015-09-05 16:11:27 -04001261 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1262 valid digest function. :py:meth:`X509Req.verify` can be used to check
1263 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001264 """
1265 request = self.signable()
1266 key = PKey()
1267 key.generate_key(TYPE_RSA, 512)
1268 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001269 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001270 # If the type has a verify method, cover that too.
1271 if getattr(request, 'verify', None) is not None:
1272 pub = request.get_pubkey()
1273 self.assertTrue(request.verify(pub))
1274 # Make another key that won't verify.
1275 key = PKey()
1276 key.generate_key(TYPE_RSA, 512)
1277 self.assertRaises(Error, request.verify, key)
1278
1279
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001280class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001281 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001282 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001283 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001284
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001285 def signable(self):
1286 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001287 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001288 """
1289 return X509Req()
1290
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001291 def test_type(self):
1292 """
Alex Gaynor31287502015-09-05 16:11:27 -04001293 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1294 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001295 """
1296 self.assertIdentical(X509Req, X509ReqType)
1297 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001298
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001299 def test_construction(self):
1300 """
Alex Gaynor31287502015-09-05 16:11:27 -04001301 :py:obj:`X509Req` takes no arguments and returns an
1302 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001303 """
1304 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001305 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001306
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001307 def test_version(self):
1308 """
Alex Gaynor31287502015-09-05 16:11:27 -04001309 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1310 certificate request. :py:obj:`X509ReqType.get_version` returns the
1311 X.509 version of the certificate request. The initial value of the
1312 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001313 """
1314 request = X509Req()
1315 self.assertEqual(request.get_version(), 0)
1316 request.set_version(1)
1317 self.assertEqual(request.get_version(), 1)
1318 request.set_version(3)
1319 self.assertEqual(request.get_version(), 3)
1320
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001321 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001322 """
Alex Gaynor31287502015-09-05 16:11:27 -04001323 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1324 with the wrong number of arguments or with a non-:py:obj:`int`
1325 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1326 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001327 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001328 request = X509Req()
1329 self.assertRaises(TypeError, request.set_version)
1330 self.assertRaises(TypeError, request.set_version, "foo")
1331 self.assertRaises(TypeError, request.set_version, 1, 2)
1332 self.assertRaises(TypeError, request.get_version, None)
1333
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001334 def test_get_subject(self):
1335 """
Alex Gaynor31287502015-09-05 16:11:27 -04001336 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1337 subject of the request and which is valid even after the request object
1338 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001339 """
1340 request = X509Req()
1341 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001342 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001343 subject.commonName = "foo"
1344 self.assertEqual(request.get_subject().commonName, "foo")
1345 del request
1346 subject.commonName = "bar"
1347 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001348
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001349 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001350 """
Alex Gaynor31287502015-09-05 16:11:27 -04001351 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1352 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001353 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001354 request = X509Req()
1355 self.assertRaises(TypeError, request.get_subject, None)
1356
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001357 def test_add_extensions(self):
1358 """
Alex Gaynor31287502015-09-05 16:11:27 -04001359 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1360 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001361 """
1362 request = X509Req()
1363 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001364 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001365 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001366 self.assertEqual(len(exts), 1)
1367 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1368 self.assertEqual(exts[0].get_critical(), 1)
1369 self.assertEqual(exts[0].get_data(), b('0\x00'))
1370
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001371 def test_get_extensions(self):
1372 """
1373 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1374 extensions added to this X509 request.
1375 """
1376 request = X509Req()
1377 exts = request.get_extensions()
1378 self.assertEqual(exts, [])
1379 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001380 X509Extension(b('basicConstraints'), True, b('CA:true')),
1381 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001382 exts = request.get_extensions()
1383 self.assertEqual(len(exts), 2)
1384 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1385 self.assertEqual(exts[0].get_critical(), 1)
1386 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1387 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1388 self.assertEqual(exts[1].get_critical(), 0)
1389 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001390
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001391 def test_add_extensions_wrong_args(self):
1392 """
Alex Gaynor31287502015-09-05 16:11:27 -04001393 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1394 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1395 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1396 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001397 """
1398 request = X509Req()
1399 self.assertRaises(TypeError, request.add_extensions)
1400 self.assertRaises(TypeError, request.add_extensions, object())
1401 self.assertRaises(ValueError, request.add_extensions, [object()])
1402 self.assertRaises(TypeError, request.add_extensions, [], None)
1403
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001404 def test_verify_wrong_args(self):
1405 """
1406 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1407 arguments or more than one argument or if passed anything other than a
1408 :py:obj:`PKey` instance as its single argument.
1409 """
1410 request = X509Req()
1411 self.assertRaises(TypeError, request.verify)
1412 self.assertRaises(TypeError, request.verify, object())
1413 self.assertRaises(TypeError, request.verify, PKey(), object())
1414
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001415 def test_verify_uninitialized_key(self):
1416 """
Alex Gaynor31287502015-09-05 16:11:27 -04001417 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1418 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001419 """
1420 request = X509Req()
1421 pkey = PKey()
1422 self.assertRaises(Error, request.verify, pkey)
1423
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001424 def test_verify_wrong_key(self):
1425 """
Alex Gaynor31287502015-09-05 16:11:27 -04001426 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1427 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1428 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001429 """
1430 request = X509Req()
1431 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001432 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001433 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1434 self.assertRaises(Error, request.verify, another_pkey)
1435
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001436 def test_verify_success(self):
1437 """
1438 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001439 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1440 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001441 """
1442 request = X509Req()
1443 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001444 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001445 self.assertEqual(True, request.verify(pkey))
1446
1447
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001448class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001449 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001450 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001451 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001452 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001453
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001454 extpem = """
1455-----BEGIN CERTIFICATE-----
1456MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1457BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1458eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1459MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1460aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1461hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1462Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1463zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1464hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1465TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
146603HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1467MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1468b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1469MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1470uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1471WpOdIpB8KksUTCzV591Nr1wd
1472-----END CERTIFICATE-----
1473 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001474
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001475 def signable(self):
1476 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001477 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001478 """
1479 return X509()
1480
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001481 def test_type(self):
1482 """
Alex Gaynor31287502015-09-05 16:11:27 -04001483 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1484 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001485 """
1486 self.assertIdentical(X509, X509Type)
1487 self.assertConsistentType(X509, 'X509')
1488
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001489 def test_construction(self):
1490 """
Alex Gaynor31287502015-09-05 16:11:27 -04001491 :py:obj:`X509` takes no arguments and returns an instance of
1492 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001493 """
1494 certificate = X509()
1495 self.assertTrue(
1496 isinstance(certificate, X509Type),
1497 "%r is of type %r, should be %r" % (certificate,
1498 type(certificate),
1499 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001500 self.assertEqual(type(X509Type).__name__, 'type')
1501 self.assertEqual(type(certificate).__name__, 'X509')
1502 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001503 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001504
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001505 def test_get_version_wrong_args(self):
1506 """
Alex Gaynor31287502015-09-05 16:11:27 -04001507 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1508 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001509 """
1510 cert = X509()
1511 self.assertRaises(TypeError, cert.get_version, None)
1512
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001513 def test_set_version_wrong_args(self):
1514 """
Alex Gaynor31287502015-09-05 16:11:27 -04001515 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1516 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001517 """
1518 cert = X509()
1519 self.assertRaises(TypeError, cert.set_version)
1520 self.assertRaises(TypeError, cert.set_version, None)
1521 self.assertRaises(TypeError, cert.set_version, 1, None)
1522
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001523 def test_version(self):
1524 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001525 :py:obj:`X509.set_version` sets the certificate version number.
1526 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001527 """
1528 cert = X509()
1529 cert.set_version(1234)
1530 self.assertEquals(cert.get_version(), 1234)
1531
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001532 def test_get_serial_number_wrong_args(self):
1533 """
Alex Gaynor31287502015-09-05 16:11:27 -04001534 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1535 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001536 """
1537 cert = X509()
1538 self.assertRaises(TypeError, cert.get_serial_number, None)
1539
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001540 def test_serial_number(self):
1541 """
Alex Gaynor31287502015-09-05 16:11:27 -04001542 The serial number of an :py:obj:`X509Type` can be retrieved and
1543 modified with :py:obj:`X509Type.get_serial_number` and
1544 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001545 """
1546 certificate = X509()
1547 self.assertRaises(TypeError, certificate.set_serial_number)
1548 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1549 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1550 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1551 self.assertEqual(certificate.get_serial_number(), 0)
1552 certificate.set_serial_number(1)
1553 self.assertEqual(certificate.get_serial_number(), 1)
1554 certificate.set_serial_number(2 ** 32 + 1)
1555 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1556 certificate.set_serial_number(2 ** 64 + 1)
1557 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001558 certificate.set_serial_number(2 ** 128 + 1)
1559 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1560
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001561 def _setBoundTest(self, which):
1562 """
Alex Gaynor31287502015-09-05 16:11:27 -04001563 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1564 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1565 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001566 """
1567 certificate = X509()
1568 set = getattr(certificate, 'set_not' + which)
1569 get = getattr(certificate, 'get_not' + which)
1570
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001571 # Starts with no value.
1572 self.assertEqual(get(), None)
1573
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001574 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001575 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001576 set(when)
1577 self.assertEqual(get(), when)
1578
1579 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001580 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001581 set(when)
1582 self.assertEqual(get(), when)
1583
1584 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001585 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001586 set(when)
1587 self.assertEqual(get(), when)
1588
1589 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001590 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001591
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001592 # The wrong number of arguments results in a TypeError.
1593 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001594 with pytest.raises(TypeError):
1595 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001596 self.assertRaises(TypeError, get, b("foo bar"))
1597
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001598 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001599
1600 def test_set_notBefore(self):
1601 """
Alex Gaynor31287502015-09-05 16:11:27 -04001602 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1603 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1604 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001605 """
1606 self._setBoundTest("Before")
1607
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001608 def test_set_notAfter(self):
1609 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001610 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001611 GENERALIZEDTIME and sets the end of the certificate's validity period
1612 to it.
1613 """
1614 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001615
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001616 def test_get_notBefore(self):
1617 """
Alex Gaynor31287502015-09-05 16:11:27 -04001618 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1619 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001620 internally.
1621 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001622 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001623 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001624
Rick Dean38a05c82009-07-18 01:41:30 -05001625 def test_get_notAfter(self):
1626 """
Alex Gaynor31287502015-09-05 16:11:27 -04001627 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1628 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001629 internally.
1630 """
1631 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001632 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001633
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001634 def test_gmtime_adj_notBefore_wrong_args(self):
1635 """
Alex Gaynor31287502015-09-05 16:11:27 -04001636 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1637 called with the wrong number of arguments or a non-:py:obj:`int`
1638 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001639 """
1640 cert = X509()
1641 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1642 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1643 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1644
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001645 def test_gmtime_adj_notBefore(self):
1646 """
Alex Gaynor31287502015-09-05 16:11:27 -04001647 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1648 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001649 """
1650 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001651 not_before_min = (
1652 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1653 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001654 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001655 not_before = datetime.strptime(
1656 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1657 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001658 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1659 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001660
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001661 def test_gmtime_adj_notAfter_wrong_args(self):
1662 """
Alex Gaynor31287502015-09-05 16:11:27 -04001663 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1664 called with the wrong number of arguments or a non-:py:obj:`int`
1665 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001666 """
1667 cert = X509()
1668 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1669 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1670 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1671
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001672 def test_gmtime_adj_notAfter(self):
1673 """
Alex Gaynor31287502015-09-05 16:11:27 -04001674 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1675 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001676 """
1677 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001678 not_after_min = (
1679 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1680 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001681 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001682 not_after = datetime.strptime(
1683 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1684 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001685 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1686 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001687
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001688 def test_has_expired_wrong_args(self):
1689 """
Alex Gaynor31287502015-09-05 16:11:27 -04001690 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1691 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001692 """
1693 cert = X509()
1694 self.assertRaises(TypeError, cert.has_expired, None)
1695
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001696 def test_has_expired(self):
1697 """
Alex Gaynor31287502015-09-05 16:11:27 -04001698 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1699 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001700 """
1701 cert = X509()
1702 cert.gmtime_adj_notAfter(-1)
1703 self.assertTrue(cert.has_expired())
1704
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001705 def test_has_not_expired(self):
1706 """
Alex Gaynor31287502015-09-05 16:11:27 -04001707 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1708 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001709 """
1710 cert = X509()
1711 cert.gmtime_adj_notAfter(2)
1712 self.assertFalse(cert.has_expired())
1713
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001714 def test_root_has_not_expired(self):
1715 """
Alex Gaynor31287502015-09-05 16:11:27 -04001716 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1717 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001718 """
1719 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1720 self.assertFalse(cert.has_expired())
1721
Rick Dean38a05c82009-07-18 01:41:30 -05001722 def test_digest(self):
1723 """
Alex Gaynor31287502015-09-05 16:11:27 -04001724 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1725 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001726 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001727 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001728 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001729 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1730 # actually matters to the assertion (ie, another arbitrary, good
1731 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001732 # Digest verified with the command:
1733 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001734 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001735 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001736
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001737 def _extcert(self, pkey, extensions):
1738 cert = X509()
1739 cert.set_pubkey(pkey)
1740 cert.get_subject().commonName = "Unit Tests"
1741 cert.get_issuer().commonName = "Unit Tests"
1742 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1743 cert.set_notBefore(when)
1744 cert.set_notAfter(when)
1745
1746 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001747 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001748 return load_certificate(
1749 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1750
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001751 def test_extension_count(self):
1752 """
Alex Gaynor31287502015-09-05 16:11:27 -04001753 :py:obj:`X509.get_extension_count` returns the number of extensions
1754 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001755 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001756 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001757 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1758 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001759 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001760 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001761
1762 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001763 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001764 self.assertEqual(c.get_extension_count(), 0)
1765
1766 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001767 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001768 self.assertEqual(c.get_extension_count(), 1)
1769
1770 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001771 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001772 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001773
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001774 def test_get_extension(self):
1775 """
Alex Gaynor31287502015-09-05 16:11:27 -04001776 :py:obj:`X509.get_extension` takes an integer and returns an
1777 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001778 """
1779 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001780 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1781 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001782 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001783 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001784
1785 cert = self._extcert(pkey, [ca, key, subjectAltName])
1786
1787 ext = cert.get_extension(0)
1788 self.assertTrue(isinstance(ext, X509Extension))
1789 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001790 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001791
1792 ext = cert.get_extension(1)
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('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001796
1797 ext = cert.get_extension(2)
1798 self.assertTrue(isinstance(ext, X509Extension))
1799 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001800 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001801
1802 self.assertRaises(IndexError, cert.get_extension, -1)
1803 self.assertRaises(IndexError, cert.get_extension, 4)
1804 self.assertRaises(TypeError, cert.get_extension, "hello")
1805
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001806 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001807 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001808 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001809 bytes and this value is reflected in the string representation of the
1810 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001811 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001812 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001813
1814 ext = cert.get_extension(3)
1815 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001816 self.assertEqual(
1817 b("DNS:altnull.python.org\x00example.com, "
1818 "email:null@python.org\x00user@example.org, "
1819 "URI:http://null.python.org\x00http://example.org, "
1820 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1821 b(str(ext)))
1822
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001823 def test_invalid_digest_algorithm(self):
1824 """
Alex Gaynor31287502015-09-05 16:11:27 -04001825 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1826 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001827 """
1828 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001829 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001830
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001831 def test_get_subject_wrong_args(self):
1832 """
Alex Gaynor31287502015-09-05 16:11:27 -04001833 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1834 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001835 """
1836 cert = X509()
1837 self.assertRaises(TypeError, cert.get_subject, None)
1838
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001839 def test_get_subject(self):
1840 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001841 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001842 """
1843 cert = load_certificate(FILETYPE_PEM, self.pemData)
1844 subj = cert.get_subject()
1845 self.assertTrue(isinstance(subj, X509Name))
1846 self.assertEquals(
1847 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001848 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1849 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001850
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001851 def test_set_subject_wrong_args(self):
1852 """
Alex Gaynor31287502015-09-05 16:11:27 -04001853 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1854 the wrong number of arguments or an argument not of type
1855 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001856 """
1857 cert = X509()
1858 self.assertRaises(TypeError, cert.set_subject)
1859 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001860 with pytest.raises(TypeError):
1861 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001862
1863 def test_set_subject(self):
1864 """
Alex Gaynor31287502015-09-05 16:11:27 -04001865 :py:obj:`X509.set_subject` changes the subject of the certificate to
1866 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001867 """
1868 cert = X509()
1869 name = cert.get_subject()
1870 name.C = 'AU'
1871 name.O = 'Unit Tests'
1872 cert.set_subject(name)
1873 self.assertEquals(
1874 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001875 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001876
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001877 def test_get_issuer_wrong_args(self):
1878 """
Alex Gaynor31287502015-09-05 16:11:27 -04001879 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1880 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001881 """
1882 cert = X509()
1883 self.assertRaises(TypeError, cert.get_issuer, None)
1884
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001885 def test_get_issuer(self):
1886 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001887 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001888 """
1889 cert = load_certificate(FILETYPE_PEM, self.pemData)
1890 subj = cert.get_issuer()
1891 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001892 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001893 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001894 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001895 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1896 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001897
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001898 def test_set_issuer_wrong_args(self):
1899 """
Alex Gaynor31287502015-09-05 16:11:27 -04001900 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1901 the wrong number of arguments or an argument not of type
1902 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001903 """
1904 cert = X509()
1905 self.assertRaises(TypeError, cert.set_issuer)
1906 self.assertRaises(TypeError, cert.set_issuer, None)
1907 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1908
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001909 def test_set_issuer(self):
1910 """
Alex Gaynor31287502015-09-05 16:11:27 -04001911 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1912 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001913 """
1914 cert = X509()
1915 name = cert.get_issuer()
1916 name.C = 'AU'
1917 name.O = 'Unit Tests'
1918 cert.set_issuer(name)
1919 self.assertEquals(
1920 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001921 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001922
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001923 def test_get_pubkey_uninitialized(self):
1924 """
Alex Gaynor31287502015-09-05 16:11:27 -04001925 When called on a certificate with no public key,
1926 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001927 """
1928 cert = X509()
1929 self.assertRaises(Error, cert.get_pubkey)
1930
Alex Gaynor7778e792016-07-03 23:38:48 -04001931 def test_set_pubkey_wrong_type(self):
1932 """
1933 :obj:`X509.set_pubkey` raises :obj:`TypeError` when given an object of
1934 the wrong type.
1935 """
1936 cert = X509()
1937 with pytest.raises(TypeError):
1938 cert.set_pubkey(object())
1939
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001940 def test_subject_name_hash_wrong_args(self):
1941 """
Alex Gaynor31287502015-09-05 16:11:27 -04001942 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1943 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001944 """
1945 cert = X509()
1946 self.assertRaises(TypeError, cert.subject_name_hash, None)
1947
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001948 def test_subject_name_hash(self):
1949 """
Alex Gaynor31287502015-09-05 16:11:27 -04001950 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1951 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001952 """
1953 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001954 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001955 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001956 [3350047874, # OpenSSL 0.9.8, MD5
1957 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001958 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001959
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001960 def test_get_signature_algorithm(self):
1961 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001962 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001963 the algorithm used to sign the certificate.
1964 """
1965 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001966 self.assertEqual(
1967 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001968
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001969 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001970 """
Alex Gaynor31287502015-09-05 16:11:27 -04001971 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1972 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001973 """
1974 # This certificate has been modified to indicate a bogus OID in the
1975 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001976 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001977-----BEGIN CERTIFICATE-----
1978MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1979EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1980cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1981MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1982EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1983CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1984AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1985+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1986hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1987BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1988FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1989dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1990aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1991MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1992jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1993PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1994tgI5
1995-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001996""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001997 cert = load_certificate(FILETYPE_PEM, certPEM)
1998 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001999
Alex Gaynor37726112016-07-04 09:51:32 -04002000 def test_sign_bad_pubkey_type(self):
2001 """
2002 :obj:`X509.sign` raises :obj:`TypeError` when called with the wrong
2003 type.
2004 """
2005 cert = X509()
2006 with pytest.raises(TypeError):
2007 cert.sign(object(), b"sha256")
2008
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04002009
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002010class X509StoreTests(TestCase):
2011 """
2012 Test for :py:obj:`OpenSSL.crypto.X509Store`.
2013 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002014
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002015 def test_type(self):
2016 """
2017 :py:obj:`X509StoreType` is a type object.
2018 """
2019 self.assertIdentical(X509Store, X509StoreType)
2020 self.assertConsistentType(X509Store, 'X509Store')
2021
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002022 def test_add_cert_wrong_args(self):
2023 store = X509Store()
2024 self.assertRaises(TypeError, store.add_cert)
2025 self.assertRaises(TypeError, store.add_cert, object())
2026 self.assertRaises(TypeError, store.add_cert, X509(), object())
2027
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002028 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002029 """
2030 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
2031 certificate store.
2032 """
2033 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002034 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002035 store.add_cert(cert)
2036
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002037 def test_add_cert_rejects_duplicate(self):
2038 """
Alex Gaynor31287502015-09-05 16:11:27 -04002039 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
2040 an attempt is made to add the same certificate to the store more than
2041 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002042 """
2043 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2044 store = X509Store()
2045 store.add_cert(cert)
2046 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002047
2048
Rick Dean623ee362009-07-17 12:22:16 -05002049class PKCS12Tests(TestCase):
2050 """
Alex Gaynor31287502015-09-05 16:11:27 -04002051 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
2052 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002053 """
2054 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
2055
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002056 def test_type(self):
2057 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002058 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002059 """
2060 self.assertIdentical(PKCS12, PKCS12Type)
2061 self.assertConsistentType(PKCS12, 'PKCS12')
2062
Rick Deanf94096c2009-07-18 14:23:06 -05002063 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002064 """
Alex Gaynor31287502015-09-05 16:11:27 -04002065 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
2066 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05002067 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002068 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05002069 self.assertEqual(None, p12.get_certificate())
2070 self.assertEqual(None, p12.get_privatekey())
2071 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05002072 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05002073
2074 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002075 """
Alex Gaynor31287502015-09-05 16:11:27 -04002076 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
2077 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
2078 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
2079 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05002080 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002081 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05002082 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002083 self.assertRaises(TypeError, p12.set_certificate, PKey())
2084 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05002085 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002086 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
2087 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05002088 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
2089 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
2090 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04002091 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05002092 self.assertRaises(TypeError, p12.set_friendlyname, 6)
2093 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05002094
2095 def test_key_only(self):
2096 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002097 A :py:obj:`PKCS12` with only a private key can be exported using
2098 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002099 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002100 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002101 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002102 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002103 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05002104 self.assertEqual(None, p12.get_certificate())
2105 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002106 try:
2107 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2108 except Error:
2109 # Some versions of OpenSSL will throw an exception
2110 # for this nearly useless PKCS12 we tried to generate:
2111 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2112 return
Rick Dean623ee362009-07-17 12:22:16 -05002113 p12 = load_pkcs12(dumped_p12, passwd)
2114 self.assertEqual(None, p12.get_ca_certificates())
2115 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002116
2117 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2118 # future this will be improved.
2119 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05002120
2121 def test_cert_only(self):
2122 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002123 A :py:obj:`PKCS12` with only a certificate can be exported using
2124 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002125 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002126 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002127 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002128 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002129 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05002130 self.assertEqual(cert, p12.get_certificate())
2131 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002132 try:
2133 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2134 except Error:
2135 # Some versions of OpenSSL will throw an exception
2136 # for this nearly useless PKCS12 we tried to generate:
2137 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2138 return
Rick Dean623ee362009-07-17 12:22:16 -05002139 p12 = load_pkcs12(dumped_p12, passwd)
2140 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002141
2142 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
2143 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2144
2145 # Oh ho. It puts the certificate into the ca certificates list, in
2146 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2147 # that to check to see if it reconstructed the certificate we expected
2148 # it to. At some point, hopefully this will change so that
2149 # p12.get_certificate() is actually what returns the loaded
2150 # certificate.
2151 self.assertEqual(
2152 cleartextCertificatePEM,
2153 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002154
Alex Gaynor31287502015-09-05 16:11:27 -04002155 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2156 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002157 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002158 Generate a PKCS12 object with components from PEM. Verify that the set
2159 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002160 """
Rick Deanf94096c2009-07-18 14:23:06 -05002161 p12 = PKCS12()
2162 if cert_pem:
2163 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2164 self.assertEqual(ret, None)
2165 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002166 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002167 self.assertEqual(ret, None)
2168 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002169 ret = p12.set_ca_certificates(
2170 (load_certificate(FILETYPE_PEM, ca_pem),)
2171 )
Rick Deanf94096c2009-07-18 14:23:06 -05002172 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002173 if friendly_name:
2174 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002175 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002176 return p12
2177
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002178 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002179 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002180 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002181 Use openssl program to confirm three components are recoverable from a
2182 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002183 """
2184 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002185 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002186 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2187 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002188 self.assertEqual(recovered_key[-len(key):], key)
2189 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002190 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002191 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2192 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002193 self.assertEqual(recovered_cert[-len(cert):], cert)
2194 if ca:
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"-cacerts", b"-nodes", b"-passin",
2197 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002198 self.assertEqual(recovered_cert[-len(ca):], ca)
2199
Stephen Holsapple38482622014-04-05 20:29:34 -07002200 def verify_pkcs12_container(self, p12):
2201 """
2202 Verify that the PKCS#12 container contains the correct client
2203 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002204
2205 :param p12: The PKCS12 instance to verify.
2206 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002207 """
2208 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2209 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002210 self.assertEqual(
2211 (client_cert_pem, client_key_pem, None),
2212 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002213
Rick Deanf94096c2009-07-18 14:23:06 -05002214 def test_load_pkcs12(self):
2215 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002216 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002217 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002218 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002219 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002220 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002221 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002222 pem,
2223 b"pkcs12",
2224 b"-export",
2225 b"-clcerts",
2226 b"-passout",
2227 b"pass:" + passwd
2228 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002229 p12 = load_pkcs12(p12_str, passphrase=passwd)
2230 self.verify_pkcs12_container(p12)
2231
Abraham Martinc5484ba2015-03-25 15:33:05 +00002232 def test_load_pkcs12_text_passphrase(self):
2233 """
2234 A PKCS12 string generated using the openssl command line can be loaded
2235 with :py:obj:`load_pkcs12` and its components extracted and examined.
2236 Using text as passphrase instead of bytes. DeprecationWarning expected.
2237 """
2238 pem = client_key_pem + client_cert_pem
2239 passwd = b"whatever"
2240 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2241 b"-passout", b"pass:" + passwd)
2242 with catch_warnings(record=True) as w:
2243 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002244 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002245
2246 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002247 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002248 WARNING_TYPE_EXPECTED
2249 ),
2250 str(w[-1].message)
2251 )
2252 self.assertIs(w[-1].category, DeprecationWarning)
2253
Abraham Martinc5484ba2015-03-25 15:33:05 +00002254 self.verify_pkcs12_container(p12)
2255
Stephen Holsapple38482622014-04-05 20:29:34 -07002256 def test_load_pkcs12_no_passphrase(self):
2257 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002258 A PKCS12 string generated using openssl command line can be loaded with
2259 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2260 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002261 """
2262 pem = client_key_pem + client_cert_pem
2263 p12_str = _runopenssl(
2264 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2265 p12 = load_pkcs12(p12_str)
2266 self.verify_pkcs12_container(p12)
2267
Stephen Holsapple38482622014-04-05 20:29:34 -07002268 def _dump_and_load(self, dump_passphrase, load_passphrase):
2269 """
2270 A helper method to dump and load a PKCS12 object.
2271 """
2272 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2273 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2274 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2275
Stephen Holsapple38482622014-04-05 20:29:34 -07002276 def test_load_pkcs12_null_passphrase_load_empty(self):
2277 """
2278 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002279 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002280 extracted and examined.
2281 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002282 self.verify_pkcs12_container(
2283 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002284
Stephen Holsapple38482622014-04-05 20:29:34 -07002285 def test_load_pkcs12_null_passphrase_load_null(self):
2286 """
2287 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002288 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002289 extracted and examined.
2290 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002291 self.verify_pkcs12_container(
2292 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002293
Stephen Holsapple38482622014-04-05 20:29:34 -07002294 def test_load_pkcs12_empty_passphrase_load_empty(self):
2295 """
2296 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002297 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002298 extracted and examined.
2299 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002300 self.verify_pkcs12_container(
2301 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002302
Stephen Holsapple38482622014-04-05 20:29:34 -07002303 def test_load_pkcs12_empty_passphrase_load_null(self):
2304 """
2305 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002306 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002307 extracted and examined.
2308 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002309 self.verify_pkcs12_container(
2310 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002311
Rick Deanee568302009-07-24 09:56:29 -05002312 def test_load_pkcs12_garbage(self):
2313 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002314 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2315 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002316 """
2317 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002318 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002319 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2320 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002321
Rick Deanf94096c2009-07-18 14:23:06 -05002322 def test_replace(self):
2323 """
Alex Gaynor31287502015-09-05 16:11:27 -04002324 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2325 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002326 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002327 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002328 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2329 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2330 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002331 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002332 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002333 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002334 self.assertEqual(1, len(p12.get_ca_certificates()))
2335 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002336 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002337 self.assertEqual(2, len(p12.get_ca_certificates()))
2338 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2339 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2340
Rick Deanf94096c2009-07-18 14:23:06 -05002341 def test_friendly_name(self):
2342 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002343 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002344 :py:obj:`PKCS12.get_friendlyname` and
2345 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2346 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002347 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002348 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002349 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002350 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002351 p12.set_friendlyname(friendly_name)
2352 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002353 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002354 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002355 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002356 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002357 # We would use the openssl program to confirm the friendly
2358 # name, but it is not possible. The pkcs12 command
2359 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002360 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002361 self.check_recovery(
2362 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2363 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002364
Rick Deanf94096c2009-07-18 14:23:06 -05002365 def test_various_empty_passphrases(self):
2366 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002367 Test that missing, None, and '' passphrases are identical for PKCS12
2368 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002369 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002370 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002371 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002372 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2373 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2374 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2375 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2376 self.check_recovery(
2377 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2378 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002379
Rick Deanf94096c2009-07-18 14:23:06 -05002380 def test_removing_ca_cert(self):
2381 """
Alex Gaynor31287502015-09-05 16:11:27 -04002382 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2383 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002384 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002385 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2386 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002387 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002388
Rick Deanf94096c2009-07-18 14:23:06 -05002389 def test_export_without_mac(self):
2390 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002391 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002392 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002393 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002394 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002395 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002396 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002397 self.check_recovery(
2398 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002399 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002400
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002401 def test_load_without_mac(self):
2402 """
2403 Loading a PKCS12 without a MAC does something other than crash.
2404 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002405 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002406 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2407 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002408 try:
2409 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2410 # The person who generated this PCKS12 should be flogged,
2411 # or better yet we should have a means to determine
2412 # whether a PCKS12 had a MAC that was verified.
2413 # Anyway, libopenssl chooses to allow it, so the
2414 # pyopenssl binding does as well.
2415 self.assertTrue(isinstance(recovered_p12, PKCS12))
2416 except Error:
2417 # Failing here with an exception is preferred as some openssl
2418 # versions do.
2419 pass
Rick Dean623ee362009-07-17 12:22:16 -05002420
Rick Dean25bcc1f2009-07-20 11:53:13 -05002421 def test_zero_len_list_for_ca(self):
2422 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002423 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002424 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002425 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002426 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002427 p12.set_ca_certificates([])
2428 self.assertEqual((), p12.get_ca_certificates())
2429 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2430 self.check_recovery(
2431 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2432 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002433
Rick Deanf94096c2009-07-18 14:23:06 -05002434 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002435 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002436 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002437 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002438 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002439 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002440 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002441 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002442
Abraham Martinc5484ba2015-03-25 15:33:05 +00002443 def test_export_without_bytes(self):
2444 """
2445 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2446 """
2447 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2448
2449 with catch_warnings(record=True) as w:
2450 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002451 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002452 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002453 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002454 WARNING_TYPE_EXPECTED
2455 ),
2456 str(w[-1].message)
2457 )
2458 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002459 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002460 dumped_p12,
2461 key=server_key_pem,
2462 cert=server_cert_pem,
2463 passwd=b"randomtext"
2464 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002465
Rick Deanf94096c2009-07-18 14:23:06 -05002466 def test_key_cert_mismatch(self):
2467 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002468 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002469 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002470 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002471 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2472 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002473
2474
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002475# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002476_cmdLineQuoteRe = re.compile(br'(\\*)"')
2477_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002478
2479
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002480def cmdLineQuote(s):
2481 """
2482 Internal method for quoting a single command-line argument.
2483
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002484 See http://www.perlmonks.org/?node_id=764004
2485
Jonathan Ballet648875f2011-07-16 14:14:58 +09002486 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002487 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002488 cmd.exe-style quoting
2489
Jonathan Ballet648875f2011-07-16 14:14:58 +09002490 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002491 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002492 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002493 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2494 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002495
2496
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002497def quoteArguments(arguments):
2498 """
2499 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002500 a similar API. This allows the list passed to
2501 :py:obj:`reactor.spawnProcess` to match the child process's
2502 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002503
Jonathan Ballet648875f2011-07-16 14:14:58 +09002504 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002505 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002506
Jonathan Ballet648875f2011-07-16 14:14:58 +09002507 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002508 :return: A space-delimited string containing quoted versions of
2509 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002510 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002511 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002512
2513
Rick Dean4c9ad612009-07-17 15:05:22 -05002514def _runopenssl(pem, *args):
2515 """
2516 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002517 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002518 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002519 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002520 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002521 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2522 for arg in args
2523 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002524 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002525 command = b"openssl " + quoteArguments(args)
2526 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002527 proc.stdin.write(pem)
2528 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002529 output = proc.stdout.read()
2530 proc.stdout.close()
2531 proc.wait()
2532 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002533
2534
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002535class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002536 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002537 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002538 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002539 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002540 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002541 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002542 """
2543 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002544
2545 assert True is key._only_public
2546 assert 2048 == key.bits()
2547 assert TYPE_RSA == key.type()
2548
2549 def test_invalid_type(self):
2550 """
2551 load_publickey doesn't support FILETYPE_TEXT.
2552 """
2553 with pytest.raises(ValueError):
2554 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2555
2556 def test_invalid_key_format(self):
2557 """
2558 load_publickey explodes on incorrect keys.
2559 """
2560 with pytest.raises(Error):
2561 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2562
2563 def test_tolerates_unicode_strings(self):
2564 """
2565 load_publickey works with text strings, not just bytes.
2566 """
2567 serialized = cleartextPublicKeyPEM.decode('ascii')
2568 key = load_publickey(FILETYPE_PEM, serialized)
2569 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2570
2571 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002572
2573
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002574class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002575 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002576 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002577
2578 Add new tests to `TestFunctions` above.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002579 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002580
2581 def test_load_privatekey_invalid_format(self):
2582 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002583 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2584 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002585 """
2586 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2587
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002588 def test_load_privatekey_invalid_passphrase_type(self):
2589 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002590 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2591 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002592 """
2593 self.assertRaises(
2594 TypeError,
2595 load_privatekey,
2596 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2597
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002598 def test_load_privatekey_wrong_args(self):
2599 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002600 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2601 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002602 """
2603 self.assertRaises(TypeError, load_privatekey)
2604
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002605 def test_load_privatekey_wrongPassphrase(self):
2606 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002607 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2608 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002609 """
2610 self.assertRaises(
2611 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002612 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002613
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002614 def test_load_privatekey_passphraseWrongType(self):
2615 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002616 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2617 a passphrase with a private key encoded in a format, that doesn't
2618 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002619 """
2620 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2621 blob = dump_privatekey(FILETYPE_ASN1, key)
2622 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002623 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002624
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002625 def test_load_privatekey_passphrase(self):
2626 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002627 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2628 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002629 """
2630 key = load_privatekey(
2631 FILETYPE_PEM, encryptedPrivateKeyPEM,
2632 encryptedPrivateKeyPEMPassphrase)
2633 self.assertTrue(isinstance(key, PKeyType))
2634
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002635 def test_load_privatekey_passphrase_exception(self):
2636 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002637 If the passphrase callback raises an exception, that exception is
2638 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002639 """
2640 def cb(ignored):
2641 raise ArithmeticError
2642
Alex Gaynor791212d2015-09-05 15:46:08 -04002643 with pytest.raises(ArithmeticError):
2644 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002645
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002646 def test_load_privatekey_wrongPassphraseCallback(self):
2647 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002648 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2649 is passed an encrypted PEM and a passphrase callback which returns an
2650 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002651 """
2652 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002653
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002654 def cb(*a):
2655 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002656 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002657 self.assertRaises(
2658 Error,
2659 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2660 self.assertTrue(called)
2661
2662 def test_load_privatekey_passphraseCallback(self):
2663 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002664 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2665 encrypted PEM string if given a passphrase callback which returns the
2666 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002667 """
2668 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002669
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002670 def cb(writing):
2671 called.append(writing)
2672 return encryptedPrivateKeyPEMPassphrase
2673 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2674 self.assertTrue(isinstance(key, PKeyType))
2675 self.assertEqual(called, [False])
2676
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002677 def test_load_privatekey_passphrase_wrong_return_type(self):
2678 """
2679 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2680 callback returns something other than a byte string.
2681 """
2682 self.assertRaises(
2683 ValueError,
2684 load_privatekey,
2685 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2686
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002687 def test_dump_privatekey_wrong_args(self):
2688 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002689 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2690 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002691 """
2692 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002693 # If cipher name is given, password is required.
2694 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002695 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002696
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002697 def test_dump_privatekey_unknown_cipher(self):
2698 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002699 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2700 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002701 """
2702 key = PKey()
2703 key.generate_key(TYPE_RSA, 512)
2704 self.assertRaises(
2705 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002706 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002707
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002708 def test_dump_privatekey_invalid_passphrase_type(self):
2709 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002710 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2711 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002712 """
2713 key = PKey()
2714 key.generate_key(TYPE_RSA, 512)
2715 self.assertRaises(
2716 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002717 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002718
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002719 def test_dump_privatekey_invalid_filetype(self):
2720 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002721 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2722 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002723 """
2724 key = PKey()
2725 key.generate_key(TYPE_RSA, 512)
2726 self.assertRaises(ValueError, dump_privatekey, 100, key)
2727
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002728 def test_load_privatekey_passphraseCallbackLength(self):
2729 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002730 :py:obj:`crypto.load_privatekey` should raise an error when the
2731 passphrase provided by the callback is too long, not silently truncate
2732 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002733 """
2734 def cb(ignored):
2735 return "a" * 1025
2736
Alex Gaynor791212d2015-09-05 15:46:08 -04002737 with pytest.raises(ValueError):
2738 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002739
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002740 def test_dump_privatekey_passphrase(self):
2741 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002742 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2743 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002744 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002745 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002746 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002747 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2748 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002749 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2750 self.assertTrue(isinstance(loadedKey, PKeyType))
2751 self.assertEqual(loadedKey.type(), key.type())
2752 self.assertEqual(loadedKey.bits(), key.bits())
2753
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002754 def test_dump_privatekey_passphraseWrongType(self):
2755 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002756 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2757 a passphrase with a private key encoded in a format, that doesn't
2758 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002759 """
2760 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002761 with pytest.raises(ValueError):
2762 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002763
Rick Dean5b7b6372009-04-01 11:34:06 -05002764 def test_dump_certificate(self):
2765 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002766 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002767 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002768 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002769 cert = load_certificate(FILETYPE_PEM, pemData)
2770 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2771 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2772 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002773 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002774 self.assertEqual(dumped_der, good_der)
2775 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2776 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2777 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2778 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Alex Gaynor316aa2c2016-09-10 14:42:53 -04002779 good_text = _runopenssl(
2780 dumped_pem, b"x509", b"-noout", b"-text", b"-nameopt", b"")
Rick Dean5b7b6372009-04-01 11:34:06 -05002781 self.assertEqual(dumped_text, good_text)
2782
Alex Gaynor37726112016-07-04 09:51:32 -04002783 def test_dump_certificate_bad_type(self):
2784 """
2785 :obj:`dump_certificate` raises a :obj:`ValueError` if it's called with
2786 a bad type.
2787 """
2788 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2789 with pytest.raises(ValueError):
2790 dump_certificate(object(), cert)
2791
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002792 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002793 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002794 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002795 """
2796 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002797 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002798 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2799 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002800
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002801 def test_dump_privatekey_asn1(self):
2802 """
2803 :py:obj:`dump_privatekey` writes a DER
2804 """
2805 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2806 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2807
Rick Dean5b7b6372009-04-01 11:34:06 -05002808 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002809 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002810 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002811 self.assertEqual(dumped_der, good_der)
2812 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2813 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2814 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002815
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002816 def test_dump_privatekey_text(self):
2817 """
2818 :py:obj:`dump_privatekey` writes a text
2819 """
2820 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2821 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2822
Rick Dean5b7b6372009-04-01 11:34:06 -05002823 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002824 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002825 self.assertEqual(dumped_text, good_text)
2826
Cory Benfield6492f7c2015-10-27 16:57:58 +09002827 def test_dump_publickey_pem(self):
2828 """
Cory Benfield11c10192015-10-27 17:23:03 +09002829 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002830 """
2831 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2832 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002833 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002834
2835 def test_dump_publickey_asn1(self):
2836 """
Cory Benfield11c10192015-10-27 17:23:03 +09002837 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002838 """
2839 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2840 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2841 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2842 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002843 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002844
Cory Benfielde02c7d82015-10-27 17:34:49 +09002845 def test_dump_publickey_invalid_type(self):
2846 """
2847 dump_publickey doesn't support FILETYPE_TEXT.
2848 """
2849 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2850
2851 with pytest.raises(ValueError):
2852 dump_publickey(FILETYPE_TEXT, key)
2853
Rick Dean5b7b6372009-04-01 11:34:06 -05002854 def test_dump_certificate_request(self):
2855 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002856 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002857 """
Alex Gaynor31287502015-09-05 16:11:27 -04002858 req = load_certificate_request(
2859 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002860 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2861 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2862 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002863 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002864 self.assertEqual(dumped_der, good_der)
2865 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2866 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2867 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2868 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Alex Gaynor316aa2c2016-09-10 14:42:53 -04002869 good_text = _runopenssl(
2870 dumped_pem, b"req", b"-noout", b"-text", b"-nameopt", b"")
Rick Dean5b7b6372009-04-01 11:34:06 -05002871 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002872 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002873
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002874 def test_dump_privatekey_passphraseCallback(self):
2875 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002876 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2877 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002878 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002879 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002880 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002881
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002882 def cb(writing):
2883 called.append(writing)
2884 return passphrase
2885 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002886 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2887 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002888 self.assertEqual(called, [True])
2889 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2890 self.assertTrue(isinstance(loadedKey, PKeyType))
2891 self.assertEqual(loadedKey.type(), key.type())
2892 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002893
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002894 def test_dump_privatekey_passphrase_exception(self):
2895 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002896 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002897 by the passphrase callback.
2898 """
2899 def cb(ignored):
2900 raise ArithmeticError
2901
2902 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002903 with pytest.raises(ArithmeticError):
2904 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002905
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002906 def test_dump_privatekey_passphraseCallbackLength(self):
2907 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002908 :py:obj:`crypto.dump_privatekey` should raise an error when the
2909 passphrase provided by the callback is too long, not silently truncate
2910 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002911 """
2912 def cb(ignored):
2913 return "a" * 1025
2914
2915 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002916 with pytest.raises(ValueError):
2917 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002918
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002919 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002920 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002921 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2922 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002923 """
2924 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2925 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2926
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002927 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002928 """
2929 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2930 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2931 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002932 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2933 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2934
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002935 def test_load_pkcs7_data_invalid(self):
2936 """
2937 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2938 :py:obj:`Error` is raised.
2939 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002940 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002941
Alex Gaynor09a386e2016-07-03 09:32:44 -04002942 def test_load_pkcs7_type_invalid(self):
2943 """
2944 If the type passed to :obj:`load_pkcs7_data`, :obj:`ValueError` is
2945 raised.
2946 """
2947 with pytest.raises(ValueError):
2948 load_pkcs7_data(object(), b"foo")
2949
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002950
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002951class LoadCertificateTests(TestCase):
2952 """
2953 Tests for :py:obj:`load_certificate_request`.
2954 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002955
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002956 def test_badFileType(self):
2957 """
2958 If the file type passed to :py:obj:`load_certificate_request` is
2959 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2960 :py:class:`ValueError` is raised.
2961 """
Alex Gaynor7778e792016-07-03 23:38:48 -04002962 with pytest.raises(ValueError):
2963 load_certificate_request(object(), b"")
2964 with pytest.raises(ValueError):
2965 load_certificate(object(), b"")
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002966
Alex Gaynor37726112016-07-04 09:51:32 -04002967 def test_bad_certificate(self):
2968 """
2969 If the bytes passed to :obj:`load_certificate` are not a valid
2970 certificate, an exception is raised.
2971 """
2972 with pytest.raises(Error):
2973 load_certificate(FILETYPE_ASN1, b"lol")
2974
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002975
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002976class PKCS7Tests(TestCase):
2977 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002978 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002979 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002980
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002981 def test_type(self):
2982 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002983 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002984 """
2985 self.assertTrue(isinstance(PKCS7Type, type))
2986 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2987
2988 # XXX This doesn't currently work.
2989 # self.assertIdentical(PKCS7, PKCS7Type)
2990
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002991 # XXX Opposite results for all these following methods
2992
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002993 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002994 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002995 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2996 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002997 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002998 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2999 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
3000
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003001 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003002 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003003 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
3004 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003005 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003006 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3007 self.assertTrue(pkcs7.type_is_signed())
3008
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003009 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003010 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003011 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
3012 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003013 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003014 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3015 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
3016
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003017 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003018 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003019 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
3020 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003021 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003022 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3023 self.assertFalse(pkcs7.type_is_enveloped())
3024
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003025 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003026 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003027 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
3028 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003029 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003030 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3031 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
3032
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003033 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003034 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003035 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
3036 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003037 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003038 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3039 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
3040
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003041 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003042 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003043 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
3044 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003045 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003046 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3047 self.assertFalse(pkcs7.type_is_data())
3048
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003049 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003050 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003051 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
3052 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003053 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003054 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3055 self.assertRaises(TypeError, pkcs7.type_is_data, None)
3056
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003057 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003058 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003059 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
3060 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003061 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003062 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3063 self.assertRaises(TypeError, pkcs7.get_type_name, None)
3064
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003065 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003066 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003067 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
3068 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003069 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003070 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04003071 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003072
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003073 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003074 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003075 If an attribute other than one of the methods tested here is accessed
3076 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
3077 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003078 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003079 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3080 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
3081
3082
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003083class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003084 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003085 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003086 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003087
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003088 def signable(self):
3089 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003090 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003091 """
3092 return NetscapeSPKI()
3093
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003094 def test_type(self):
3095 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003096 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
3097 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003098 """
3099 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
3100 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
3101
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003102 def test_construction(self):
3103 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003104 :py:obj:`NetscapeSPKI` returns an instance of
3105 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003106 """
3107 nspki = NetscapeSPKI()
3108 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
3109
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003110 def test_invalid_attribute(self):
3111 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003112 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
3113 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003114 """
3115 nspki = NetscapeSPKI()
3116 self.assertRaises(AttributeError, lambda: nspki.foo)
3117
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003118 def test_b64_encode(self):
3119 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003120 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
3121 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003122 """
3123 nspki = NetscapeSPKI()
3124 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003125 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003126
3127
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003128class TestRevoked(object):
3129 """
3130 Please add test cases for the Revoked class here if possible. This class
3131 holds the new py.test style tests.
3132 """
3133 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3134 """
3135 The get_reason method on the Revoked class checks to see if the
3136 extension is NID_crl_reason and should skip it otherwise. This test
3137 loads a CRL with extensions it should ignore.
3138 """
3139 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3140 revoked = crl.get_revoked()
3141 reason = revoked[1].get_reason()
3142 assert reason == b'Unspecified'
3143
3144 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3145 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3146 revoked = crl.get_revoked()
3147 revoked[1].set_reason(None)
3148 reason = revoked[1].get_reason()
3149 assert reason is None
3150
3151
Rick Dean536ba022009-07-24 23:57:27 -05003152class RevokedTests(TestCase):
3153 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003154 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3155 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003156 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003157
Rick Dean536ba022009-07-24 23:57:27 -05003158 def test_construction(self):
3159 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003160 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003161 that it is empty.
3162 """
3163 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003164 self.assertTrue(isinstance(revoked, Revoked))
3165 self.assertEquals(type(revoked), Revoked)
3166 self.assertEquals(revoked.get_serial(), b('00'))
3167 self.assertEquals(revoked.get_rev_date(), None)
3168 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003169
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003170 def test_construction_wrong_args(self):
3171 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003172 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3173 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003174 """
3175 self.assertRaises(TypeError, Revoked, None)
3176 self.assertRaises(TypeError, Revoked, 1)
3177 self.assertRaises(TypeError, Revoked, "foo")
3178
Rick Dean536ba022009-07-24 23:57:27 -05003179 def test_serial(self):
3180 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003181 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003182 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003183 with grace.
3184 """
3185 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003186 ret = revoked.set_serial(b('10b'))
3187 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003188 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003189 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05003190
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003191 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003192 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003193 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05003194
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003195 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05003196 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003197 self.assertRaises(TypeError, revoked.get_serial, 1)
3198 self.assertRaises(TypeError, revoked.get_serial, None)
3199 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003200
Rick Dean536ba022009-07-24 23:57:27 -05003201 def test_date(self):
3202 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003203 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003204 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003205 with grace.
3206 """
3207 revoked = Revoked()
3208 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003209 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003210
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003211 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003212 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003213 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003214 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003215 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003216
Rick Dean6385faf2009-07-26 00:07:47 -05003217 def test_reason(self):
3218 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003219 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003220 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003221 as "set". Likewise, each reason of all_reasons() must work.
3222 """
3223 revoked = Revoked()
3224 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003225 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003226 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003227 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003228 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003229 self.assertEquals(
3230 reason.lower().replace(b(' '), b('')),
3231 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003232 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003233
3234 revoked.set_reason(None)
3235 self.assertEqual(revoked.get_reason(), None)
3236
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003237 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003238 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003239 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003240 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003241 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003242 """
3243 revoked = Revoked()
3244 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003245 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003246
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003247 def test_get_reason_wrong_arguments(self):
3248 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003249 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3250 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003251 """
3252 revoked = Revoked()
3253 self.assertRaises(TypeError, revoked.get_reason, None)
3254 self.assertRaises(TypeError, revoked.get_reason, 1)
3255 self.assertRaises(TypeError, revoked.get_reason, "foo")
3256
3257
Rick Dean536ba022009-07-24 23:57:27 -05003258class CRLTests(TestCase):
3259 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003260 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003261 """
3262 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3263 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3264
Dan Sully44e767a2016-06-04 18:05:27 -07003265 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3266 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3267 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3268 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3269 intermediate_server_cert = load_certificate(
3270 FILETYPE_PEM, intermediate_server_cert_pem)
3271 intermediate_server_key = load_privatekey(
3272 FILETYPE_PEM, intermediate_server_key_pem)
3273
Rick Dean536ba022009-07-24 23:57:27 -05003274 def test_construction(self):
3275 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003276 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003277 that it is empty
3278 """
3279 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003280 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003281 self.assertEqual(crl.get_revoked(), None)
3282
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003283 def test_construction_wrong_args(self):
3284 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003285 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3286 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003287 """
3288 self.assertRaises(TypeError, CRL, 1)
3289 self.assertRaises(TypeError, CRL, "")
3290 self.assertRaises(TypeError, CRL, None)
3291
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003292 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003293 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003294 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003295 """
3296 crl = CRL()
3297 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003298 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003299 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003300 revoked.set_serial(b('3ab'))
3301 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003302 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003303 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003304
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003305 def test_export_pem(self):
3306 """
3307 If not passed a format, ``CRL.export`` returns a "PEM" format string
3308 representing a serial number, a revoked reason, and certificate issuer
3309 information.
3310 """
3311 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003312 # PEM format
3313 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003314 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003315
3316 # These magic values are based on the way the CRL above was constructed
3317 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003318 text.index(b('Serial Number: 03AB'))
3319 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003320 text.index(
3321 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3322 )
3323
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003324 def test_export_der(self):
3325 """
3326 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3327 "DER" format string representing a serial number, a revoked reason, and
3328 certificate issuer information.
3329 """
3330 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003331
3332 # DER format
3333 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003334 text = _runopenssl(
3335 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3336 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003337 text.index(b('Serial Number: 03AB'))
3338 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003339 text.index(
3340 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3341 )
3342
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003343 def test_export_text(self):
3344 """
3345 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3346 text format string like the one produced by the openssl command line
3347 tool.
3348 """
3349 crl = self._get_crl()
3350
3351 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3352 text = _runopenssl(
3353 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3354 )
Rick Dean536ba022009-07-24 23:57:27 -05003355
3356 # text format
3357 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3358 self.assertEqual(text, dumped_text)
3359
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003360 def test_export_custom_digest(self):
3361 """
3362 If passed the name of a digest function, ``CRL.export`` uses a
3363 signature algorithm based on that digest function.
3364 """
3365 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003366 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003367 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3368 text.index(b('Signature Algorithm: sha1'))
3369
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003370 def test_export_md5_digest(self):
3371 """
3372 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3373 not emit a deprecation warning.
3374 """
3375 crl = self._get_crl()
3376 with catch_warnings(record=True) as catcher:
3377 simplefilter("always")
3378 self.assertEqual(0, len(catcher))
3379 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3380 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3381 text.index(b('Signature Algorithm: md5'))
3382
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003383 def test_export_default_digest(self):
3384 """
3385 If not passed the name of a digest function, ``CRL.export`` uses a
3386 signature algorithm based on MD5 and emits a deprecation warning.
3387 """
3388 crl = self._get_crl()
3389 with catch_warnings(record=True) as catcher:
3390 simplefilter("always")
3391 dumped_crl = crl.export(self.cert, self.pkey)
3392 self.assertEqual(
3393 "The default message digest (md5) is deprecated. "
3394 "Pass the name of a message digest explicitly.",
3395 str(catcher[0].message),
3396 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003397 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3398 text.index(b('Signature Algorithm: md5'))
3399
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003400 def test_export_invalid(self):
3401 """
3402 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003403 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003404 """
3405 crl = CRL()
3406 self.assertRaises(Error, crl.export, X509(), PKey())
3407
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003408 def test_add_revoked_keyword(self):
3409 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003410 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003411 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003412 """
3413 crl = CRL()
3414 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003415 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003416 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003417 crl.add_revoked(revoked=revoked)
3418 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3419
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003420 def test_export_wrong_args(self):
3421 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003422 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003423 four arguments, or with arguments other than the certificate,
3424 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003425 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003426 """
3427 crl = CRL()
3428 self.assertRaises(TypeError, crl.export)
3429 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003430 with pytest.raises(TypeError):
3431 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3432 with pytest.raises(TypeError):
3433 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3434 with pytest.raises(TypeError):
3435 crl.export(self.cert, None, FILETYPE_PEM, 10)
3436 with pytest.raises(TypeError):
3437 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003438 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3439
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003440 def test_export_unknown_filetype(self):
3441 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003442 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003443 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3444 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003445 """
3446 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003447 with pytest.raises(ValueError):
3448 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003449
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003450 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003451 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003452 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003453 in a :py:obj:`ValueError` being raised.
3454 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003455 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003456 self.assertRaises(
3457 ValueError,
3458 crl.export,
3459 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3460 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003461
Rick Dean536ba022009-07-24 23:57:27 -05003462 def test_get_revoked(self):
3463 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003464 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003465 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3466 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003467 """
3468 crl = CRL()
3469
3470 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003471 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003472 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003473 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003474 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003475 revoked.set_serial(b('100'))
3476 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003477 crl.add_revoked(revoked)
3478
3479 revs = crl.get_revoked()
3480 self.assertEqual(len(revs), 2)
3481 self.assertEqual(type(revs[0]), Revoked)
3482 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003483 self.assertEqual(revs[0].get_serial(), b('03AB'))
3484 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003485 self.assertEqual(revs[0].get_rev_date(), now)
3486 self.assertEqual(revs[1].get_rev_date(), now)
3487
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003488 def test_get_revoked_wrong_args(self):
3489 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003490 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3491 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003492 """
3493 crl = CRL()
3494 self.assertRaises(TypeError, crl.get_revoked, None)
3495 self.assertRaises(TypeError, crl.get_revoked, 1)
3496 self.assertRaises(TypeError, crl.get_revoked, "")
3497 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3498
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003499 def test_add_revoked_wrong_args(self):
3500 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003501 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3502 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003503 """
3504 crl = CRL()
3505 self.assertRaises(TypeError, crl.add_revoked)
3506 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3507 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3508
Rick Dean536ba022009-07-24 23:57:27 -05003509 def test_load_crl(self):
3510 """
3511 Load a known CRL and inspect its revocations. Both
3512 PEM and DER formats are loaded.
3513 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003514 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003515 revs = crl.get_revoked()
3516 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003517 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003518 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003519 self.assertEqual(revs[1].get_serial(), b('0100'))
3520 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003521
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003522 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003523 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003524 revs = crl.get_revoked()
3525 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003526 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003527 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003528 self.assertEqual(revs[1].get_serial(), b('0100'))
3529 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003530
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003531 def test_load_crl_wrong_args(self):
3532 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003533 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3534 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003535 """
3536 self.assertRaises(TypeError, load_crl)
3537 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3538 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3539
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003540 def test_load_crl_bad_filetype(self):
3541 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003542 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3543 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003544 """
3545 self.assertRaises(ValueError, load_crl, 100, crlData)
3546
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003547 def test_load_crl_bad_data(self):
3548 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003549 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3550 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003551 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003552 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003553
Dan Sully44e767a2016-06-04 18:05:27 -07003554 def test_get_issuer(self):
3555 """
3556 Load a known CRL and assert its issuer's common name is
3557 what we expect from the encoded crlData string.
3558 """
3559 crl = load_crl(FILETYPE_PEM, crlData)
3560 self.assertTrue(isinstance(crl.get_issuer(), X509Name))
3561 self.assertEqual(crl.get_issuer().CN, 'Testing Root CA')
3562
Dominic Chenf05b2122015-10-13 16:32:35 +00003563 def test_dump_crl(self):
3564 """
3565 The dumped CRL matches the original input.
3566 """
3567 crl = load_crl(FILETYPE_PEM, crlData)
3568 buf = dump_crl(FILETYPE_PEM, crl)
3569 assert buf == crlData
3570
Dan Sully44e767a2016-06-04 18:05:27 -07003571 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3572 """
3573 Create a CRL.
3574
3575 :param list[X509] certs: A list of certificates to revoke.
3576 :rtype: CRL
3577 """
3578 crl = CRL()
3579 for cert in certs:
3580 revoked = Revoked()
3581 # FIXME: This string splicing is an unfortunate implementation
3582 # detail that has been reported in
3583 # https://github.com/pyca/pyopenssl/issues/258
3584 serial = hex(cert.get_serial_number())[2:].encode('utf-8')
3585 revoked.set_serial(serial)
3586 revoked.set_reason(b'unspecified')
3587 revoked.set_rev_date(b'20140601000000Z')
3588 crl.add_revoked(revoked)
3589 crl.set_version(1)
3590 crl.set_lastUpdate(b'20140601000000Z')
3591 crl.set_nextUpdate(b'20180601000000Z')
3592 crl.sign(issuer_cert, issuer_key, digest=b'sha512')
3593 return crl
3594
3595 def test_verify_with_revoked(self):
3596 """
3597 :func:`verify_certificate` raises error when an intermediate
3598 certificate is revoked.
3599 """
3600 store = X509Store()
3601 store.add_cert(self.root_cert)
3602 store.add_cert(self.intermediate_cert)
3603 root_crl = self._make_test_crl(
3604 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3605 intermediate_crl = self._make_test_crl(
3606 self.intermediate_cert, self.intermediate_key, certs=[])
3607 store.add_crl(root_crl)
3608 store.add_crl(intermediate_crl)
3609 store.set_flags(
3610 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3611 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3612 e = self.assertRaises(
3613 X509StoreContextError, store_ctx.verify_certificate)
3614 self.assertEqual(e.args[0][2], 'certificate revoked')
3615
3616 def test_verify_with_missing_crl(self):
3617 """
3618 :func:`verify_certificate` raises error when an intermediate
3619 certificate's CRL is missing.
3620 """
3621 store = X509Store()
3622 store.add_cert(self.root_cert)
3623 store.add_cert(self.intermediate_cert)
3624 root_crl = self._make_test_crl(
3625 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3626 store.add_crl(root_crl)
3627 store.set_flags(
3628 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3629 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3630 e = self.assertRaises(
3631 X509StoreContextError, store_ctx.verify_certificate)
3632 self.assertEqual(e.args[0][2], 'unable to get certificate CRL')
3633 self.assertEqual(
3634 e.certificate.get_subject().CN, 'intermediate-service')
3635
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003636
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003637class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003638 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003639 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003640 """
3641 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3642 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003643 intermediate_server_cert = load_certificate(
3644 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003645
3646 def test_valid(self):
3647 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003648 :py:obj:`verify_certificate` returns ``None`` when called with a
3649 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003650 """
3651 store = X509Store()
3652 store.add_cert(self.root_cert)
3653 store.add_cert(self.intermediate_cert)
3654 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003655 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003656
3657 def test_reuse(self):
3658 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003659 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003660 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003661 """
3662 store = X509Store()
3663 store.add_cert(self.root_cert)
3664 store.add_cert(self.intermediate_cert)
3665 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003666 self.assertEqual(store_ctx.verify_certificate(), None)
3667 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003668
3669 def test_trusted_self_signed(self):
3670 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003671 :py:obj:`verify_certificate` returns ``None`` when called with a
3672 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003673 """
3674 store = X509Store()
3675 store.add_cert(self.root_cert)
3676 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003677 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003678
3679 def test_untrusted_self_signed(self):
3680 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003681 :py:obj:`verify_certificate` raises error when a self-signed
3682 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003683 """
3684 store = X509Store()
3685 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003686 with pytest.raises(X509StoreContextError) as exc:
3687 store_ctx.verify_certificate()
3688
3689 assert exc.value.args[0][2] == 'self signed certificate'
3690 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003691
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003692 def test_invalid_chain_no_root(self):
3693 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003694 :py:obj:`verify_certificate` raises error when a root certificate is
3695 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003696 """
3697 store = X509Store()
3698 store.add_cert(self.intermediate_cert)
3699 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003700
3701 with pytest.raises(X509StoreContextError) as exc:
3702 store_ctx.verify_certificate()
3703
3704 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3705 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003706
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003707 def test_invalid_chain_no_intermediate(self):
3708 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003709 :py:obj:`verify_certificate` raises error when an intermediate
3710 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003711 """
3712 store = X509Store()
3713 store.add_cert(self.root_cert)
3714 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003715
Alex Gaynor85b49702015-09-05 16:30:59 -04003716 with pytest.raises(X509StoreContextError) as exc:
3717 store_ctx.verify_certificate()
3718
3719 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3720 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003721
Stephen Holsapple46a09252015-02-12 14:45:43 -08003722 def test_modification_pre_verify(self):
3723 """
3724 :py:obj:`verify_certificate` can use a store context modified after
3725 instantiation.
3726 """
3727 store_bad = X509Store()
3728 store_bad.add_cert(self.intermediate_cert)
3729 store_good = X509Store()
3730 store_good.add_cert(self.root_cert)
3731 store_good.add_cert(self.intermediate_cert)
3732 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003733
3734 with pytest.raises(X509StoreContextError) as exc:
3735 store_ctx.verify_certificate()
3736
3737 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3738 assert exc.value.certificate.get_subject().CN == 'intermediate'
3739
Stephen Holsapple46a09252015-02-12 14:45:43 -08003740 store_ctx.set_store(store_good)
3741 self.assertEqual(store_ctx.verify_certificate(), None)
3742
3743
James Yonan7c2e5d32010-02-27 05:45:50 -07003744class SignVerifyTests(TestCase):
3745 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003746 Tests for :py:obj:`OpenSSL.crypto.sign` and
3747 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003748 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003749
James Yonan7c2e5d32010-02-27 05:45:50 -07003750 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003751 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003752 :py:obj:`sign` generates a cryptographic signature which
3753 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003754 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003755 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003756 "It was a bright cold day in April, and the clocks were striking "
3757 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3758 "effort to escape the vile wind, slipped quickly through the "
3759 "glass doors of Victory Mansions, though not quickly enough to "
3760 "prevent a swirl of gritty dust from entering along with him.")
3761
3762 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003763 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003764 # verify the content with this cert
3765 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3766 # certificate unrelated to priv_key, used to trigger an error
3767 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003768
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003769 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003770 sig = sign(priv_key, content, digest)
3771
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003772 # Verify the signature of content, will throw an exception if
3773 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003774 verify(good_cert, sig, content, digest)
3775
3776 # This should fail because the certificate doesn't match the
3777 # private key that was used to sign the content.
3778 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3779
3780 # This should fail because we've "tainted" the content after
3781 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003782 self.assertRaises(
3783 Error, verify,
3784 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003785
3786 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003787 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003788 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003789 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003790 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003791
Abraham Martinc5484ba2015-03-25 15:33:05 +00003792 def test_sign_verify_with_text(self):
3793 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003794 :py:obj:`sign` generates a cryptographic signature which
3795 :py:obj:`verify` can check. Deprecation warnings raised because using
3796 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003797 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003798 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003799 b"It was a bright cold day in April, and the clocks were striking "
3800 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3801 b"effort to escape the vile wind, slipped quickly through the "
3802 b"glass doors of Victory Mansions, though not quickly enough to "
3803 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003804 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003805
3806 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3807 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3808 for digest in ['md5', 'sha1']:
3809 with catch_warnings(record=True) as w:
3810 simplefilter("always")
3811 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003812
3813 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003814 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003815 WARNING_TYPE_EXPECTED
3816 ),
3817 str(w[-1].message)
3818 )
3819 self.assertIs(w[-1].category, DeprecationWarning)
3820
Abraham Martinc5484ba2015-03-25 15:33:05 +00003821 with catch_warnings(record=True) as w:
3822 simplefilter("always")
3823 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003824
3825 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003826 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003827 WARNING_TYPE_EXPECTED
3828 ),
3829 str(w[-1].message)
3830 )
3831 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003832
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003833 def test_sign_nulls(self):
3834 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003835 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003836 """
3837 content = b("Watch out! \0 Did you see it?")
3838 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3839 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3840 sig = sign(priv_key, content, "sha1")
3841 verify(good_cert, sig, content, "sha1")
3842
Colleen Murphye09399b2016-03-01 17:40:49 -08003843 def test_sign_with_large_key(self):
3844 """
3845 :py:obj:`sign` produces a signature for a string when using a long key.
3846 """
3847 content = b(
3848 "It was a bright cold day in April, and the clocks were striking "
3849 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3850 "effort to escape the vile wind, slipped quickly through the "
3851 "glass doors of Victory Mansions, though not quickly enough to "
3852 "prevent a swirl of gritty dust from entering along with him.")
3853
3854 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3855 sign(priv_key, content, "sha1")
3856
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003857
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003858class EllipticCurveTests(TestCase):
3859 """
3860 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3861 :py:obj:`get_elliptic_curves`.
3862 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003863
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003864 def test_set(self):
3865 """
3866 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3867 """
3868 self.assertIsInstance(get_elliptic_curves(), set)
3869
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003870 def test_some_curves(self):
3871 """
3872 If :py:mod:`cryptography` has elliptic curve support then the set
3873 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3874 it.
3875
3876 There could be an OpenSSL that violates this assumption. If so, this
3877 test will fail and we'll find out.
3878 """
3879 curves = get_elliptic_curves()
3880 if lib.Cryptography_HAS_EC:
3881 self.assertTrue(curves)
3882 else:
3883 self.assertFalse(curves)
3884
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003885 def test_a_curve(self):
3886 """
3887 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3888 supported curve.
3889 """
3890 curves = get_elliptic_curves()
3891 if curves:
3892 curve = next(iter(curves))
3893 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3894 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003895 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003896
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003897 def test_not_a_curve(self):
3898 """
3899 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3900 with a name which does not identify a supported curve.
3901 """
3902 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003903 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003904
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003905 def test_repr(self):
3906 """
3907 The string representation of a curve object includes simply states the
3908 object is a curve and what its name is.
3909 """
3910 curves = get_elliptic_curves()
3911 if curves:
3912 curve = next(iter(curves))
3913 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3914
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003915 def test_to_EC_KEY(self):
3916 """
3917 The curve object can export a version of itself as an EC_KEY* via the
3918 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3919 """
3920 curves = get_elliptic_curves()
3921 if curves:
3922 curve = next(iter(curves))
3923 # It's not easy to assert anything about this object. However, see
3924 # leakcheck/crypto.py for a test that demonstrates it at least does
3925 # not leak memory.
3926 curve._to_EC_KEY()
3927
3928
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003929class EllipticCurveFactory(object):
3930 """
3931 A helper to get the names of two curves.
3932 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003933
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003934 def __init__(self):
3935 curves = iter(get_elliptic_curves())
3936 try:
3937 self.curve_name = next(curves).name
3938 self.another_curve_name = next(curves).name
3939 except StopIteration:
3940 self.curve_name = self.another_curve_name = None
3941
3942
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003943class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3944 """
3945 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3946 """
3947 curve_factory = EllipticCurveFactory()
3948
3949 if curve_factory.curve_name is None:
3950 skip = "There are no curves available there can be no curve objects."
3951
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003952 def anInstance(self):
3953 """
3954 Get the curve object for an arbitrary curve supported by the system.
3955 """
3956 return get_elliptic_curve(self.curve_factory.curve_name)
3957
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003958 def anotherInstance(self):
3959 """
3960 Get the curve object for an arbitrary curve supported by the system -
3961 but not the one returned by C{anInstance}.
3962 """
3963 return get_elliptic_curve(self.curve_factory.another_curve_name)
3964
3965
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003966class EllipticCurveHashTests(TestCase):
3967 """
3968 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3969 as an item in a :py:type:`dict` or :py:type:`set`).
3970 """
3971 curve_factory = EllipticCurveFactory()
3972
3973 if curve_factory.curve_name is None:
3974 skip = "There are no curves available there can be no curve objects."
3975
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003976 def test_contains(self):
3977 """
3978 The ``in`` operator reports that a :py:type:`set` containing a curve
3979 does contain that curve.
3980 """
3981 curve = get_elliptic_curve(self.curve_factory.curve_name)
3982 curves = set([curve])
3983 self.assertIn(curve, curves)
3984
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003985 def test_does_not_contain(self):
3986 """
3987 The ``in`` operator reports that a :py:type:`set` not containing a
3988 curve does not contain that curve.
3989 """
3990 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003991 curves = set([
3992 get_elliptic_curve(self.curve_factory.another_curve_name)
3993 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003994 self.assertNotIn(curve, curves)