blob: e75e3ade581f7dc1543ff635044d08581095afcf [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 Gaynore7f51982016-09-11 11:48:14 -040018from six import 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 (
Alex Chanc6077062016-11-18 13:53:39 +000049 EqualityTestsMixin, is_consistent_type, TestCase, WARNING_TYPE_EXPECTED
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040050)
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
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -040081"""
Rick Dean94e46fd2009-07-18 14:51:24 -050082
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -040098"""
Rick Dean94e46fd2009-07-18 14:51:24 -050099
Alex Gaynore7f51982016-09-11 11:48:14 -0400100intermediate_cert_pem = b"""-----BEGIN CERTIFICATE-----
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700101MIICVzCCAcCgAwIBAgIRAMPzhm6//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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400115"""
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700116
Alex Gaynore7f51982016-09-11 11:48:14 -0400117intermediate_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700118MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400132"""
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700133
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400148"""
Rick Dean94e46fd2009-07-18 14:51:24 -0500149
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400165""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500166
Alex Gaynore7f51982016-09-11 11:48:14 -0400167intermediate_server_cert_pem = b"""-----BEGIN CERTIFICATE-----
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700168MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400182"""
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700183
Alex Gaynore7f51982016-09-11 11:48:14 -0400184intermediate_server_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700185MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400199"""
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700200
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400215"""
Rick Dean94e46fd2009-07-18 14:51:24 -0500216
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400232""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400233
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400252"""
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400253
Alex Gaynore7f51982016-09-11 11:48:14 -0400254cleartextPrivateKeyPEM = normalize_privatekey_pem(b"""\
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400255-----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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400270""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400271
Alex Gaynore7f51982016-09-11 11:48:14 -0400272cleartextCertificateRequestPEM = b"""-----BEGIN CERTIFICATE REQUEST-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400273MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
274EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
275ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
276BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
277E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
278xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
279gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
280Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
281oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
282-----END CERTIFICATE REQUEST-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400283"""
Rick Dean5b7b6372009-04-01 11:34:06 -0500284
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400303"""
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400304
Alex Gaynore7f51982016-09-11 11:48:14 -0400305encryptedPrivateKeyPEMPassphrase = b"foobar"
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400306
Cory Benfield6492f7c2015-10-27 16:57:58 +0900307
Alex Gaynore7f51982016-09-11 11:48:14 -0400308cleartextPublicKeyPEM = b"""-----BEGIN PUBLIC KEY-----
Cory Benfield6492f7c2015-10-27 16:57:58 +0900309MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
310gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
31190qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
312ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
313XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
3148Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
315ywIDAQAB
316-----END PUBLIC KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400317"""
Cory Benfield6492f7c2015-10-27 16:57:58 +0900318
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
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -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
Alex Gaynore7f51982016-09-11 11:48:14 -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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400379"""
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400380
Alex Gaynore7f51982016-09-11 11:48:14 -0400381crlDataUnsupportedExtension = b"""\
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400382-----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-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400418"""
Paul Kehrer5e3dd4c2016-03-11 09:58:28 -0400419
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.
Alex Gaynore7f51982016-09-11 11:48:14 -0400423inconsistentPrivateKeyPEM = b"""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400424MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
4255kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
426OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
427zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
428nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
429HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
430oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
431-----END RSA PRIVATE KEY-----
Alex Gaynore7f51982016-09-11 11:48:14 -0400432"""
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400433
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400434# certificate with NULL bytes in subjectAltName and common name
435
Alex Gaynore7f51982016-09-11 11:48:14 -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=
Alex Gaynore7f51982016-09-11 11:48:14 -0400463-----END CERTIFICATE-----"""
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400464
Alex Gaynore7f51982016-09-11 11:48:14 -0400465large_key_pem = b"""-----BEGIN RSA PRIVATE KEY-----
Colleen Murphye09399b2016-03-01 17:40:49 -0800466MIIJYgIBAAKCAg4AtRua8eIeevRfsj+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/
Alex Gaynore7f51982016-09-11 11:48:14 -0400517-----END RSA PRIVATE KEY-----"""
Colleen Murphye09399b2016-03-01 17:40:49 -0800518
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
Alex Chanc6077062016-11-18 13:53:39 +0000527@pytest.fixture
528def x509_data():
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400529 """
Alex Chanc6077062016-11-18 13:53:39 +0000530 Create a new private key and start a certificate request (for a test
531 to finish in one way or another).
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400532 """
Alex Chanc6077062016-11-18 13:53:39 +0000533 # Basic setup stuff to generate a certificate
534 pkey = PKey()
535 pkey.generate_key(TYPE_RSA, 384)
536 req = X509Req()
537 req.set_pubkey(pkey)
538 # Authority good you have.
539 req.get_subject().commonName = "Yoda root CA"
540 x509 = X509()
541 subject = x509.get_subject()
542 subject.commonName = req.get_subject().commonName
543 x509.set_issuer(subject)
544 x509.set_pubkey(pkey)
545 now = datetime.now()
546 expire = datetime.now() + timedelta(days=100)
547 x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
548 x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
549 yield pkey, x509
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400550
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400551
Alex Chanc6077062016-11-18 13:53:39 +0000552class TestX509Ext(object):
553 """
554 Tests for `OpenSSL.crypto.X509Extension`.
555 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800556
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400557 def test_str(self):
558 """
Alex Chanc6077062016-11-18 13:53:39 +0000559 The string representation of `X509Extension` instances as
560 returned by `str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400561 """
562 # This isn't necessarily the best string representation. Perhaps it
563 # will be changed/improved in the future.
Alex Chanc6077062016-11-18 13:53:39 +0000564 assert (
565 str(X509Extension(b'basicConstraints', True, b'CA:false')) ==
566 'CA:FALSE'
567 )
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400568
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400569 def test_type(self):
570 """
Alex Chanc6077062016-11-18 13:53:39 +0000571 `X509Extension` and `X509ExtensionType` refer to the same type object
572 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400573 """
Alex Chanc6077062016-11-18 13:53:39 +0000574 assert X509Extension is X509ExtensionType
575 assert is_consistent_type(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400576 X509Extension,
Alex Gaynore7f51982016-09-11 11:48:14 -0400577 'X509Extension', b'basicConstraints', True, b'CA:true')
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400578
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500579 def test_construction(self):
580 """
Alex Chanc6077062016-11-18 13:53:39 +0000581 `X509Extension` accepts an extension type name, a critical flag,
582 and an extension value and returns an `X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500583 """
Alex Gaynore7f51982016-09-11 11:48:14 -0400584 basic = X509Extension(b'basicConstraints', True, b'CA:true')
Alex Chanc6077062016-11-18 13:53:39 +0000585 assert isinstance(basic, X509ExtensionType)
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500586
Alex Chanc6077062016-11-18 13:53:39 +0000587 comment = X509Extension(b'nsComment', False, b'pyOpenSSL unit test')
588 assert isinstance(comment, X509ExtensionType)
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500589
Alex Chanc6077062016-11-18 13:53:39 +0000590 @pytest.mark.parametrize('type_name, critical, value', [
591 (b'thisIsMadeUp', False, b'hi'),
592 (b'basicConstraints', False, b'blah blah'),
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500593
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500594 # Exercise a weird one (an extension which uses the r2i method). This
595 # exercises the codepath that requires a non-NULL ctx to be passed to
596 # X509V3_EXT_nconf. It can't work now because we provide no
597 # configuration database. It might be made to work in the future.
Alex Chanc6077062016-11-18 13:53:39 +0000598 (b'proxyCertInfo', True,
599 b'language:id-ppl-anyLanguage,pathlen:1,policy:text:AB')
600 ])
601 def test_invalid_extension(self, type_name, critical, value):
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500602 """
Alex Chanc6077062016-11-18 13:53:39 +0000603 `X509Extension` raises something if it is passed a bad
604 extension name or value.
605 """
606 with pytest.raises(Error):
607 X509Extension(type_name, critical, value)
608
609 @pytest.mark.parametrize('critical_flag', [True, False])
610 def test_get_critical(self, critical_flag):
611 """
612 `X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500613 extension's critical flag.
614 """
Alex Chanc6077062016-11-18 13:53:39 +0000615 ext = X509Extension(b'basicConstraints', critical_flag, b'CA:true')
616 assert ext.get_critical() == critical_flag
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500617
Alex Chanc6077062016-11-18 13:53:39 +0000618 @pytest.mark.parametrize('short_name, value', [
619 (b'basicConstraints', b'CA:true'),
620 (b'nsComment', b'foo bar'),
621 ])
622 def test_get_short_name(self, short_name, value):
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500623 """
Alex Chanc6077062016-11-18 13:53:39 +0000624 `X509ExtensionType.get_short_name` returns a string giving the
Alex Gaynor31287502015-09-05 16:11:27 -0400625 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500626 """
Alex Chanc6077062016-11-18 13:53:39 +0000627 ext = X509Extension(short_name, True, value)
628 assert ext.get_short_name() == short_name
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500629
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400630 def test_get_data(self):
631 """
Alex Chanc6077062016-11-18 13:53:39 +0000632 `X509Extension.get_data` returns a string giving the data of
Alex Gaynor31287502015-09-05 16:11:27 -0400633 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400634 """
Alex Gaynore7f51982016-09-11 11:48:14 -0400635 ext = X509Extension(b'basicConstraints', True, b'CA:true')
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400636 # Expect to get back the DER encoded form of CA:true.
Alex Chanc6077062016-11-18 13:53:39 +0000637 assert ext.get_data() == b'0\x03\x01\x01\xff'
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400638
Alex Chanc6077062016-11-18 13:53:39 +0000639 def test_unused_subject(self, x509_data):
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400640 """
Alex Chanc6077062016-11-18 13:53:39 +0000641 The `subject` parameter to `X509Extension` may be provided for an
642 extension which does not use it and is ignored in this case.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400643 """
Alex Chanc6077062016-11-18 13:53:39 +0000644 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400645 ext1 = X509Extension(
Alex Chanc6077062016-11-18 13:53:39 +0000646 b'basicConstraints', False, b'CA:TRUE', subject=x509)
647 x509.add_extensions([ext1])
648 x509.sign(pkey, 'sha1')
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400649 # This is a little lame. Can we think of a better way?
Alex Chanc6077062016-11-18 13:53:39 +0000650 text = dump_certificate(FILETYPE_TEXT, x509)
651 assert b'X509v3 Basic Constraints:' in text
652 assert b'CA:TRUE' in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400653
Alex Chanc6077062016-11-18 13:53:39 +0000654 def test_subject(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400655 """
Alex Chanc6077062016-11-18 13:53:39 +0000656 If an extension requires a subject, the `subject` parameter to
657 `X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400658 """
Alex Chanc6077062016-11-18 13:53:39 +0000659 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400660 ext3 = X509Extension(
Alex Chanc6077062016-11-18 13:53:39 +0000661 b'subjectKeyIdentifier', False, b'hash', subject=x509)
662 x509.add_extensions([ext3])
663 x509.sign(pkey, 'sha1')
664 text = dump_certificate(FILETYPE_TEXT, x509)
665 assert b'X509v3 Subject Key Identifier:' in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400666
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400667 def test_missing_subject(self):
668 """
Alex Chanc6077062016-11-18 13:53:39 +0000669 If an extension requires a subject and the `subject` parameter
Alex Gaynor31287502015-09-05 16:11:27 -0400670 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400671 """
Alex Chanc6077062016-11-18 13:53:39 +0000672 with pytest.raises(Error):
673 X509Extension(b'subjectKeyIdentifier', False, b'hash')
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400674
Alex Chanc6077062016-11-18 13:53:39 +0000675 @pytest.mark.parametrize('bad_obj', [
676 True,
677 object(),
678 "hello",
679 [],
680 ])
681 def test_invalid_subject(self, bad_obj):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400682 """
Alex Chanc6077062016-11-18 13:53:39 +0000683 If the `subject` parameter is given a value which is not an
684 `X509` instance, `TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400685 """
Alex Chanc6077062016-11-18 13:53:39 +0000686 with pytest.raises(TypeError):
687 X509Extension(
688 'basicConstraints', False, 'CA:TRUE', subject=bad_obj)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400689
Alex Chanc6077062016-11-18 13:53:39 +0000690 def test_unused_issuer(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400691 """
Alex Chanc6077062016-11-18 13:53:39 +0000692 The `issuer` parameter to `X509Extension` may be provided for an
693 extension which does not use it and is ignored in this case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400694 """
Alex Chanc6077062016-11-18 13:53:39 +0000695 pkey, x509 = x509_data
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400696 ext1 = X509Extension(
Alex Chanc6077062016-11-18 13:53:39 +0000697 b'basicConstraints', False, b'CA:TRUE', issuer=x509)
698 x509.add_extensions([ext1])
699 x509.sign(pkey, 'sha1')
700 text = dump_certificate(FILETYPE_TEXT, x509)
701 assert b'X509v3 Basic Constraints:' in text
702 assert b'CA:TRUE' in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400703
Alex Chanc6077062016-11-18 13:53:39 +0000704 def test_issuer(self, x509_data):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400705 """
Alex Chanc6077062016-11-18 13:53:39 +0000706 If an extension requires an issuer, the `issuer` parameter to
707 `X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400708 """
Alex Chanc6077062016-11-18 13:53:39 +0000709 pkey, x509 = x509_data
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400710 ext2 = X509Extension(
Alex Gaynore7f51982016-09-11 11:48:14 -0400711 b'authorityKeyIdentifier', False, b'issuer:always',
Alex Chanc6077062016-11-18 13:53:39 +0000712 issuer=x509)
713 x509.add_extensions([ext2])
714 x509.sign(pkey, 'sha1')
715 text = dump_certificate(FILETYPE_TEXT, x509)
716 assert b'X509v3 Authority Key Identifier:' in text
717 assert b'DirName:/CN=Yoda root CA' in text
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400718
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400719 def test_missing_issuer(self):
720 """
Alex Chanc6077062016-11-18 13:53:39 +0000721 If an extension requires an issue and the `issuer` parameter is
722 given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400723 """
Alex Chanc6077062016-11-18 13:53:39 +0000724 with pytest.raises(Error):
725 X509Extension(
726 b'authorityKeyIdentifier',
727 False, b'keyid:always,issuer:always')
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400728
Alex Chanc6077062016-11-18 13:53:39 +0000729 @pytest.mark.parametrize('bad_obj', [
730 True,
731 object(),
732 "hello",
733 [],
734 ])
735 def test_invalid_issuer(self, bad_obj):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400736 """
Alex Chanc6077062016-11-18 13:53:39 +0000737 If the `issuer` parameter is given a value which is not an
738 `X509` instance, `TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400739 """
Alex Chanc6077062016-11-18 13:53:39 +0000740 with pytest.raises(TypeError):
741 X509Extension(
742 'basicConstraints', False, 'keyid:always,issuer:always',
743 issuer=bad_obj)
Rick Dean47262da2009-07-08 16:17:17 -0500744
745
Paul Kehrer72d968b2016-07-29 15:31:04 +0800746class TestPKey(object):
747 """
748 py.test-based tests for :class:`OpenSSL.crypto.PKey`.
749
750 If possible, add new tests here.
751 """
752
753 def test_convert_from_cryptography_private_key(self):
754 """
755 PKey.from_cryptography_key creates a proper private PKey.
756 """
757 key = serialization.load_pem_private_key(
758 intermediate_key_pem, None, backend
759 )
760 pkey = PKey.from_cryptography_key(key)
761
762 assert isinstance(pkey, PKey)
763 assert pkey.bits() == key.key_size
764 assert pkey._only_public is False
765 assert pkey._initialized is True
766
767 def test_convert_from_cryptography_public_key(self):
768 """
769 PKey.from_cryptography_key creates a proper public PKey.
770 """
771 key = serialization.load_pem_public_key(cleartextPublicKeyPEM, backend)
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 True
777 assert pkey._initialized is True
778
779 def test_convert_from_cryptography_unsupported_type(self):
780 """
781 PKey.from_cryptography_key raises TypeError with an unsupported type.
782 """
783 key = serialization.load_pem_private_key(
784 ec_private_key_pem, None, backend
785 )
786 with pytest.raises(TypeError):
787 PKey.from_cryptography_key(key)
788
789 def test_convert_public_pkey_to_cryptography_key(self):
790 """
791 PKey.to_cryptography_key creates a proper cryptography public key.
792 """
793 pkey = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
794 key = pkey.to_cryptography_key()
795
796 assert isinstance(key, rsa.RSAPublicKey)
797 assert pkey.bits() == key.key_size
798
799 def test_convert_private_pkey_to_cryptography_key(self):
800 """
801 PKey.to_cryptography_key creates a proper cryptography private key.
802 """
803 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
804 key = pkey.to_cryptography_key()
805
806 assert isinstance(key, rsa.RSAPrivateKey)
807 assert pkey.bits() == key.key_size
808
809
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400810class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500811 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900812 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500813 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400814
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400815 def test_type(self):
816 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900817 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
818 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400819 """
820 self.assertIdentical(PKey, PKeyType)
821 self.assertConsistentType(PKey, 'PKey')
822
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500823 def test_construction(self):
824 """
Alex Gaynor31287502015-09-05 16:11:27 -0400825 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
826 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500827 """
828 self.assertRaises(TypeError, PKey, None)
829 key = PKey()
830 self.assertTrue(
831 isinstance(key, PKeyType),
832 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
833
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500834 def test_pregeneration(self):
835 """
Alex Gaynor31287502015-09-05 16:11:27 -0400836 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
837 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
838 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500839 """
840 key = PKey()
841 self.assertEqual(key.type(), 0)
842 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400843 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500844
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500845 def test_failedGeneration(self):
846 """
Alex Gaynor31287502015-09-05 16:11:27 -0400847 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
848 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
849 the second giving the number of bits to generate. If an invalid type
850 is specified or generation fails, :py:exc:`Error` is raised. If an
851 invalid number of bits is specified, :py:exc:`ValueError` or
852 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500853 """
854 key = PKey()
855 self.assertRaises(TypeError, key.generate_key)
856 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
857 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
858 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500859
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500860 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
861 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500862
Alex Gaynor5bb2bd12016-07-03 10:48:32 -0400863 with pytest.raises(TypeError):
864 key.generate_key(TYPE_RSA, object())
865
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500866 # XXX RSA generation for small values of bits is fairly buggy in a wide
867 # range of OpenSSL versions. I need to figure out what the safe lower
868 # bound for a reasonable number of OpenSSL versions is and explicitly
869 # check for that in the wrapper. The failure behavior is typically an
870 # infinite loop inside OpenSSL.
871
872 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500873
874 # XXX DSA generation seems happy with any number of bits. The DSS
875 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
876 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500877 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500878 # So, it doesn't seem possible to make generate_key fail for
879 # TYPE_DSA with a bits argument which is at least an int.
880
881 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
882
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500883 def test_rsaGeneration(self):
884 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900885 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
886 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500887 """
888 bits = 128
889 key = PKey()
890 key.generate_key(TYPE_RSA, bits)
891 self.assertEqual(key.type(), TYPE_RSA)
892 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400893 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500894
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500895 def test_dsaGeneration(self):
896 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900897 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
898 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500899 """
900 # 512 is a magic number. The DSS (Digital Signature Standard)
901 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
902 # will silently promote any value below 512 to 512.
903 bits = 512
904 key = PKey()
905 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800906 # self.assertEqual(key.type(), TYPE_DSA)
907 # self.assertEqual(key.bits(), bits)
908 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500909
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500910 def test_regeneration(self):
911 """
Alex Gaynor31287502015-09-05 16:11:27 -0400912 :py:meth:`PKeyType.generate_key` can be called multiple times on the
913 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500914 """
915 key = PKey()
916 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400917 key.generate_key(type, bits)
918 self.assertEqual(key.type(), type)
919 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500920
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400921 def test_inconsistentKey(self):
922 """
Alex Gaynor31287502015-09-05 16:11:27 -0400923 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
924 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400925 """
926 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400927 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400928
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400929 def test_check_wrong_args(self):
930 """
Alex Gaynor31287502015-09-05 16:11:27 -0400931 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
932 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400933 """
934 self.assertRaises(TypeError, PKey().check, None)
935 self.assertRaises(TypeError, PKey().check, object())
936 self.assertRaises(TypeError, PKey().check, 1)
937
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400938 def test_check_public_key(self):
939 """
940 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
941 part of the key is available.
942 """
943 # A trick to get a public-only key
944 key = PKey()
945 key.generate_key(TYPE_RSA, 512)
946 cert = X509()
947 cert.set_pubkey(key)
948 pub = cert.get_pubkey()
949 self.assertRaises(TypeError, pub.check)
950
951
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400952class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500953 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900954 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500955 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400956
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500957 def _x509name(self, **attrs):
958 # XXX There's no other way to get a new X509Name yet.
959 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400960 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400961
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500962 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400963 def key(attr):
964 return attr[1]
965 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500966 for k, v in attrs:
967 setattr(name, k, v)
968 return name
969
Rick Deane15b1472009-07-09 15:53:42 -0500970 def test_type(self):
971 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900972 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500973 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400974 self.assertIdentical(X509Name, X509NameType)
975 self.assertEqual(X509NameType.__name__, 'X509Name')
976 self.assertTrue(isinstance(X509NameType, type))
977
Rick Deane15b1472009-07-09 15:53:42 -0500978 name = self._x509name()
979 self.assertTrue(
980 isinstance(name, X509NameType),
981 "%r is of type %r, should be %r" % (
982 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500983
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400984 def test_onlyStringAttributes(self):
985 """
Alex Gaynor31287502015-09-05 16:11:27 -0400986 Attempting to set a non-:py:data:`str` attribute name on an
987 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
988 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400989 """
990 name = self._x509name()
991 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400992 # rejected. Sorry, you're wrong. unicode is automatically converted
993 # to str outside of the control of X509Name, so there's no way to
994 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800995
Alex Gaynor31287502015-09-05 16:11:27 -0400996 # Also, this used to test str subclasses, but that test is less
997 # relevant now that the implementation is in Python instead of C. Also
998 # PyPy automatically converts str subclasses to str when they are
999 # passed to setattr, so we can't test it on PyPy. Apparently CPython
1000 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001001 self.assertRaises(TypeError, setattr, name, None, "hello")
1002 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001003
1004 def test_setInvalidAttribute(self):
1005 """
Alex Gaynor31287502015-09-05 16:11:27 -04001006 Attempting to set any attribute name on an :py:class:`X509NameType`
1007 instance for which no corresponding NID is defined causes
1008 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -04001009 """
1010 name = self._x509name()
1011 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
1012
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001013 def test_attributes(self):
1014 """
Alex Gaynor31287502015-09-05 16:11:27 -04001015 :py:class:`X509NameType` instances have attributes for each standard
1016 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001017 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001018 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001019 name.commonName = "foo"
Alex Gaynor37726112016-07-04 09:51:32 -04001020 assert name.commonName == "foo"
1021 assert name.CN == "foo"
1022
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001023 name.CN = "baz"
Alex Gaynor37726112016-07-04 09:51:32 -04001024 assert name.commonName == "baz"
1025 assert name.CN == "baz"
1026
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001027 name.commonName = "bar"
Alex Gaynor37726112016-07-04 09:51:32 -04001028 assert name.commonName == "bar"
1029 assert name.CN == "bar"
1030
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001031 name.CN = "quux"
Alex Gaynor37726112016-07-04 09:51:32 -04001032 assert name.commonName == "quux"
1033 assert name.CN == "quux"
1034
1035 assert name.OU is None
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001036
Alex Gaynor7778e792016-07-03 23:38:48 -04001037 with pytest.raises(AttributeError):
1038 name.foobar
1039
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001040 def test_copy(self):
1041 """
Alex Gaynor31287502015-09-05 16:11:27 -04001042 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
1043 with all the same attributes as an existing :py:class:`X509NameType`
1044 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001045 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001046 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001047
1048 copy = X509Name(name)
1049 self.assertEqual(copy.commonName, "foo")
1050 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001051
1052 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001053 copy.commonName = "baz"
1054 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001055
1056 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -05001057 name.emailAddress = "quux@example.com"
1058 self.assertEqual(copy.emailAddress, "bar@example.com")
1059
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001060 def test_repr(self):
1061 """
Alex Gaynor31287502015-09-05 16:11:27 -04001062 :py:func:`repr` passed an :py:class:`X509NameType` instance should
1063 return a string containing a description of the type and the NIDs which
1064 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001065 """
1066 name = self._x509name(commonName="foo", emailAddress="bar")
1067 self.assertEqual(
1068 repr(name),
1069 "<X509Name object '/emailAddress=bar/CN=foo'>")
1070
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001071 def test_comparison(self):
1072 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001073 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001074 """
1075 def _equality(a, b, assertTrue, assertFalse):
1076 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
1077 assertFalse(a != b)
1078 assertTrue(b == a)
1079 assertFalse(b != a)
1080
1081 def assertEqual(a, b):
1082 _equality(a, b, self.assertTrue, self.assertFalse)
1083
1084 # Instances compare equal to themselves.
1085 name = self._x509name()
1086 assertEqual(name, name)
1087
1088 # Empty instances should compare equal to each other.
1089 assertEqual(self._x509name(), self._x509name())
1090
1091 # Instances with equal NIDs should compare equal to each other.
1092 assertEqual(self._x509name(commonName="foo"),
1093 self._x509name(commonName="foo"))
1094
1095 # Instance with equal NIDs set using different aliases should compare
1096 # equal to each other.
1097 assertEqual(self._x509name(commonName="foo"),
1098 self._x509name(CN="foo"))
1099
1100 # Instances with more than one NID with the same values should compare
1101 # equal to each other.
1102 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
1103 self._x509name(commonName="foo", OU="bar"))
1104
1105 def assertNotEqual(a, b):
1106 _equality(a, b, self.assertFalse, self.assertTrue)
1107
1108 # Instances with different values for the same NID should not compare
1109 # equal to each other.
1110 assertNotEqual(self._x509name(CN="foo"),
1111 self._x509name(CN="bar"))
1112
1113 # Instances with different NIDs should not compare equal to each other.
1114 assertNotEqual(self._x509name(CN="foo"),
1115 self._x509name(OU="foo"))
1116
Alex Gaynor7778e792016-07-03 23:38:48 -04001117 assertNotEqual(self._x509name(), object())
1118
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -05001119 def _inequality(a, b, assertTrue, assertFalse):
1120 assertTrue(a < b)
1121 assertTrue(a <= b)
1122 assertTrue(b > a)
1123 assertTrue(b >= a)
1124 assertFalse(a > b)
1125 assertFalse(a >= b)
1126 assertFalse(b < a)
1127 assertFalse(b <= a)
1128
1129 def assertLessThan(a, b):
1130 _inequality(a, b, self.assertTrue, self.assertFalse)
1131
1132 # An X509Name with a NID with a value which sorts less than the value
1133 # of the same NID on another X509Name compares less than the other
1134 # X509Name.
1135 assertLessThan(self._x509name(CN="abc"),
1136 self._x509name(CN="def"))
1137
1138 def assertGreaterThan(a, b):
1139 _inequality(a, b, self.assertFalse, self.assertTrue)
1140
1141 # An X509Name with a NID with a value which sorts greater than the
1142 # value of the same NID on another X509Name compares greater than the
1143 # other X509Name.
1144 assertGreaterThan(self._x509name(CN="def"),
1145 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001146
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001147 def test_hash(self):
1148 """
Alex Gaynor31287502015-09-05 16:11:27 -04001149 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1150 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001151 """
1152 a = self._x509name(CN="foo")
1153 b = self._x509name(CN="foo")
1154 self.assertEqual(a.hash(), b.hash())
1155 a.CN = "bar"
1156 self.assertNotEqual(a.hash(), b.hash())
1157
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001158 def test_der(self):
1159 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001160 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001161 """
1162 a = self._x509name(CN="foo", C="US")
1163 self.assertEqual(
1164 a.der(),
Alex Gaynore7f51982016-09-11 11:48:14 -04001165 b'0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
1166 b'1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo')
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001167
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001168 def test_get_components(self):
1169 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001170 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1171 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001172 giving the NIDs and associated values which make up the name.
1173 """
1174 a = self._x509name()
1175 self.assertEqual(a.get_components(), [])
1176 a.CN = "foo"
Alex Gaynore7f51982016-09-11 11:48:14 -04001177 self.assertEqual(a.get_components(), [(b"CN", b"foo")])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001178 a.organizationalUnitName = "bar"
1179 self.assertEqual(
1180 a.get_components(),
Alex Gaynore7f51982016-09-11 11:48:14 -04001181 [(b"CN", b"foo"), (b"OU", b"bar")])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001182
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001183 def test_load_nul_byte_attribute(self):
1184 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001185 An :py:class:`OpenSSL.crypto.X509Name` from an
1186 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001187 NUL byte in the value of one of its attributes.
1188 """
1189 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1190 subject = cert.get_subject()
1191 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001192 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001193
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001194 def test_setAttributeFailure(self):
1195 """
1196 If the value of an attribute cannot be set for some reason then
1197 :py:class:`OpenSSL.crypto.Error` is raised.
1198 """
1199 name = self._x509name()
1200 # This value is too long
1201 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1202
1203
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001204class _PKeyInteractionTestsMixin:
1205 """
1206 Tests which involve another thing and a PKey.
1207 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001208
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001209 def signable(self):
1210 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001211 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1212 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001213 """
1214 raise NotImplementedError()
1215
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001216 def test_signWithUngenerated(self):
1217 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001218 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1219 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001220 """
1221 request = self.signable()
1222 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001223 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001224
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001225 def test_signWithPublicKey(self):
1226 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001227 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1228 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001229 """
1230 request = self.signable()
1231 key = PKey()
1232 key.generate_key(TYPE_RSA, 512)
1233 request.set_pubkey(key)
1234 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001235 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001236
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001237 def test_signWithUnknownDigest(self):
1238 """
Alex Gaynor31287502015-09-05 16:11:27 -04001239 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1240 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001241 """
1242 request = self.signable()
1243 key = PKey()
1244 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001245 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001246
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001247 def test_sign(self):
1248 """
Alex Gaynor31287502015-09-05 16:11:27 -04001249 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1250 valid digest function. :py:meth:`X509Req.verify` can be used to check
1251 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001252 """
1253 request = self.signable()
1254 key = PKey()
1255 key.generate_key(TYPE_RSA, 512)
1256 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001257 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001258 # If the type has a verify method, cover that too.
1259 if getattr(request, 'verify', None) is not None:
1260 pub = request.get_pubkey()
1261 self.assertTrue(request.verify(pub))
1262 # Make another key that won't verify.
1263 key = PKey()
1264 key.generate_key(TYPE_RSA, 512)
1265 self.assertRaises(Error, request.verify, key)
1266
1267
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001268class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001269 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001270 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001271 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001272
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001273 def signable(self):
1274 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001275 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001276 """
1277 return X509Req()
1278
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001279 def test_type(self):
1280 """
Alex Gaynor31287502015-09-05 16:11:27 -04001281 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1282 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001283 """
1284 self.assertIdentical(X509Req, X509ReqType)
1285 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001286
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001287 def test_construction(self):
1288 """
Alex Gaynor31287502015-09-05 16:11:27 -04001289 :py:obj:`X509Req` takes no arguments and returns an
1290 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001291 """
1292 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001293 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001294
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001295 def test_version(self):
1296 """
Alex Gaynor31287502015-09-05 16:11:27 -04001297 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1298 certificate request. :py:obj:`X509ReqType.get_version` returns the
1299 X.509 version of the certificate request. The initial value of the
1300 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001301 """
1302 request = X509Req()
1303 self.assertEqual(request.get_version(), 0)
1304 request.set_version(1)
1305 self.assertEqual(request.get_version(), 1)
1306 request.set_version(3)
1307 self.assertEqual(request.get_version(), 3)
1308
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001309 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001310 """
Alex Gaynor31287502015-09-05 16:11:27 -04001311 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1312 with the wrong number of arguments or with a non-:py:obj:`int`
1313 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1314 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001315 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001316 request = X509Req()
1317 self.assertRaises(TypeError, request.set_version)
1318 self.assertRaises(TypeError, request.set_version, "foo")
1319 self.assertRaises(TypeError, request.set_version, 1, 2)
1320 self.assertRaises(TypeError, request.get_version, None)
1321
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001322 def test_get_subject(self):
1323 """
Alex Gaynor31287502015-09-05 16:11:27 -04001324 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1325 subject of the request and which is valid even after the request object
1326 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001327 """
1328 request = X509Req()
1329 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001330 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001331 subject.commonName = "foo"
1332 self.assertEqual(request.get_subject().commonName, "foo")
1333 del request
1334 subject.commonName = "bar"
1335 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001336
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001337 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001338 """
Alex Gaynor31287502015-09-05 16:11:27 -04001339 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1340 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001341 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001342 request = X509Req()
1343 self.assertRaises(TypeError, request.get_subject, None)
1344
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001345 def test_add_extensions(self):
1346 """
Alex Gaynor31287502015-09-05 16:11:27 -04001347 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1348 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001349 """
1350 request = X509Req()
1351 request.add_extensions([
Alex Gaynore7f51982016-09-11 11:48:14 -04001352 X509Extension(b'basicConstraints', True, b'CA:false')])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001353 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001354 self.assertEqual(len(exts), 1)
Alex Gaynore7f51982016-09-11 11:48:14 -04001355 self.assertEqual(exts[0].get_short_name(), b'basicConstraints')
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001356 self.assertEqual(exts[0].get_critical(), 1)
Alex Gaynore7f51982016-09-11 11:48:14 -04001357 self.assertEqual(exts[0].get_data(), b'0\x00')
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001358
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001359 def test_get_extensions(self):
1360 """
1361 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1362 extensions added to this X509 request.
1363 """
1364 request = X509Req()
1365 exts = request.get_extensions()
1366 self.assertEqual(exts, [])
1367 request.add_extensions([
Alex Gaynore7f51982016-09-11 11:48:14 -04001368 X509Extension(b'basicConstraints', True, b'CA:true'),
1369 X509Extension(b'keyUsage', False, b'digitalSignature')])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001370 exts = request.get_extensions()
1371 self.assertEqual(len(exts), 2)
Alex Gaynore7f51982016-09-11 11:48:14 -04001372 self.assertEqual(exts[0].get_short_name(), b'basicConstraints')
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001373 self.assertEqual(exts[0].get_critical(), 1)
Alex Gaynore7f51982016-09-11 11:48:14 -04001374 self.assertEqual(exts[0].get_data(), b'0\x03\x01\x01\xff')
1375 self.assertEqual(exts[1].get_short_name(), b'keyUsage')
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001376 self.assertEqual(exts[1].get_critical(), 0)
Alex Gaynore7f51982016-09-11 11:48:14 -04001377 self.assertEqual(exts[1].get_data(), b'\x03\x02\x07\x80')
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001378
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001379 def test_add_extensions_wrong_args(self):
1380 """
Alex Gaynor31287502015-09-05 16:11:27 -04001381 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1382 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1383 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1384 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001385 """
1386 request = X509Req()
1387 self.assertRaises(TypeError, request.add_extensions)
1388 self.assertRaises(TypeError, request.add_extensions, object())
1389 self.assertRaises(ValueError, request.add_extensions, [object()])
1390 self.assertRaises(TypeError, request.add_extensions, [], None)
1391
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001392 def test_verify_wrong_args(self):
1393 """
1394 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1395 arguments or more than one argument or if passed anything other than a
1396 :py:obj:`PKey` instance as its single argument.
1397 """
1398 request = X509Req()
1399 self.assertRaises(TypeError, request.verify)
1400 self.assertRaises(TypeError, request.verify, object())
1401 self.assertRaises(TypeError, request.verify, PKey(), object())
1402
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001403 def test_verify_uninitialized_key(self):
1404 """
Alex Gaynor31287502015-09-05 16:11:27 -04001405 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1406 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001407 """
1408 request = X509Req()
1409 pkey = PKey()
1410 self.assertRaises(Error, request.verify, pkey)
1411
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001412 def test_verify_wrong_key(self):
1413 """
Alex Gaynor31287502015-09-05 16:11:27 -04001414 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1415 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1416 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001417 """
1418 request = X509Req()
1419 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001420 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001421 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1422 self.assertRaises(Error, request.verify, another_pkey)
1423
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001424 def test_verify_success(self):
1425 """
1426 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001427 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1428 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 self.assertEqual(True, request.verify(pkey))
1434
1435
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001436class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001437 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001438 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001439 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001440 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001441
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001442 extpem = """
1443-----BEGIN CERTIFICATE-----
1444MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1445BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1446eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1447MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1448aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1449hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1450Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1451zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1452hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1453TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
145403HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1455MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1456b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1457MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1458uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1459WpOdIpB8KksUTCzV591Nr1wd
1460-----END CERTIFICATE-----
1461 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001462
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001463 def signable(self):
1464 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001465 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001466 """
1467 return X509()
1468
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001469 def test_type(self):
1470 """
Alex Gaynor31287502015-09-05 16:11:27 -04001471 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1472 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001473 """
1474 self.assertIdentical(X509, X509Type)
1475 self.assertConsistentType(X509, 'X509')
1476
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001477 def test_construction(self):
1478 """
Alex Gaynor31287502015-09-05 16:11:27 -04001479 :py:obj:`X509` takes no arguments and returns an instance of
1480 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001481 """
1482 certificate = X509()
1483 self.assertTrue(
1484 isinstance(certificate, X509Type),
1485 "%r is of type %r, should be %r" % (certificate,
1486 type(certificate),
1487 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001488 self.assertEqual(type(X509Type).__name__, 'type')
1489 self.assertEqual(type(certificate).__name__, 'X509')
1490 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001491 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001492
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001493 def test_get_version_wrong_args(self):
1494 """
Alex Gaynor31287502015-09-05 16:11:27 -04001495 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1496 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001497 """
1498 cert = X509()
1499 self.assertRaises(TypeError, cert.get_version, None)
1500
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001501 def test_set_version_wrong_args(self):
1502 """
Alex Gaynor31287502015-09-05 16:11:27 -04001503 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1504 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001505 """
1506 cert = X509()
1507 self.assertRaises(TypeError, cert.set_version)
1508 self.assertRaises(TypeError, cert.set_version, None)
1509 self.assertRaises(TypeError, cert.set_version, 1, None)
1510
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001511 def test_version(self):
1512 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001513 :py:obj:`X509.set_version` sets the certificate version number.
1514 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001515 """
1516 cert = X509()
1517 cert.set_version(1234)
1518 self.assertEquals(cert.get_version(), 1234)
1519
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001520 def test_get_serial_number_wrong_args(self):
1521 """
Alex Gaynor31287502015-09-05 16:11:27 -04001522 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1523 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001524 """
1525 cert = X509()
1526 self.assertRaises(TypeError, cert.get_serial_number, None)
1527
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001528 def test_serial_number(self):
1529 """
Alex Gaynor31287502015-09-05 16:11:27 -04001530 The serial number of an :py:obj:`X509Type` can be retrieved and
1531 modified with :py:obj:`X509Type.get_serial_number` and
1532 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001533 """
1534 certificate = X509()
1535 self.assertRaises(TypeError, certificate.set_serial_number)
1536 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1537 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1538 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1539 self.assertEqual(certificate.get_serial_number(), 0)
1540 certificate.set_serial_number(1)
1541 self.assertEqual(certificate.get_serial_number(), 1)
1542 certificate.set_serial_number(2 ** 32 + 1)
1543 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1544 certificate.set_serial_number(2 ** 64 + 1)
1545 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001546 certificate.set_serial_number(2 ** 128 + 1)
1547 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1548
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001549 def _setBoundTest(self, which):
1550 """
Alex Gaynor31287502015-09-05 16:11:27 -04001551 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1552 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1553 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001554 """
1555 certificate = X509()
1556 set = getattr(certificate, 'set_not' + which)
1557 get = getattr(certificate, 'get_not' + which)
1558
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001559 # Starts with no value.
1560 self.assertEqual(get(), None)
1561
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001562 # GMT (Or is it UTC?) -exarkun
Alex Gaynore7f51982016-09-11 11:48:14 -04001563 when = b"20040203040506Z"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001564 set(when)
1565 self.assertEqual(get(), when)
1566
1567 # A plus two hours and thirty minutes offset
Alex Gaynore7f51982016-09-11 11:48:14 -04001568 when = b"20040203040506+0530"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001569 set(when)
1570 self.assertEqual(get(), when)
1571
1572 # A minus one hour fifteen minutes offset
Alex Gaynore7f51982016-09-11 11:48:14 -04001573 when = b"20040203040506-0115"
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001574 set(when)
1575 self.assertEqual(get(), when)
1576
1577 # An invalid string results in a ValueError
Alex Gaynore7f51982016-09-11 11:48:14 -04001578 self.assertRaises(ValueError, set, b"foo bar")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001579
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001580 # The wrong number of arguments results in a TypeError.
1581 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001582 with pytest.raises(TypeError):
1583 set(b"20040203040506Z", b"20040203040506Z")
Alex Gaynore7f51982016-09-11 11:48:14 -04001584 self.assertRaises(TypeError, get, b"foo bar")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001585
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001586 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001587
1588 def test_set_notBefore(self):
1589 """
Alex Gaynor31287502015-09-05 16:11:27 -04001590 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1591 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1592 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001593 """
1594 self._setBoundTest("Before")
1595
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001596 def test_set_notAfter(self):
1597 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001598 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001599 GENERALIZEDTIME and sets the end of the certificate's validity period
1600 to it.
1601 """
1602 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001603
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001604 def test_get_notBefore(self):
1605 """
Alex Gaynor31287502015-09-05 16:11:27 -04001606 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1607 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001608 internally.
1609 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001610 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynore7f51982016-09-11 11:48:14 -04001611 self.assertEqual(cert.get_notBefore(), b"20090325123658Z")
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001612
Rick Dean38a05c82009-07-18 01:41:30 -05001613 def test_get_notAfter(self):
1614 """
Alex Gaynor31287502015-09-05 16:11:27 -04001615 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1616 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001617 internally.
1618 """
1619 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynore7f51982016-09-11 11:48:14 -04001620 self.assertEqual(cert.get_notAfter(), b"20170611123658Z")
Rick Dean38a05c82009-07-18 01:41:30 -05001621
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001622 def test_gmtime_adj_notBefore_wrong_args(self):
1623 """
Alex Gaynor31287502015-09-05 16:11:27 -04001624 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1625 called with the wrong number of arguments or a non-:py:obj:`int`
1626 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001627 """
1628 cert = X509()
1629 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1630 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1631 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1632
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001633 def test_gmtime_adj_notBefore(self):
1634 """
Alex Gaynor31287502015-09-05 16:11:27 -04001635 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1636 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001637 """
1638 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001639 not_before_min = (
1640 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1641 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001642 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001643 not_before = datetime.strptime(
1644 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1645 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001646 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1647 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001648
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001649 def test_gmtime_adj_notAfter_wrong_args(self):
1650 """
Alex Gaynor31287502015-09-05 16:11:27 -04001651 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1652 called with the wrong number of arguments or a non-:py:obj:`int`
1653 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001654 """
1655 cert = X509()
1656 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1657 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1658 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1659
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001660 def test_gmtime_adj_notAfter(self):
1661 """
Alex Gaynor31287502015-09-05 16:11:27 -04001662 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1663 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001664 """
1665 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001666 not_after_min = (
1667 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1668 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001669 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001670 not_after = datetime.strptime(
1671 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1672 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001673 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1674 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001675
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001676 def test_has_expired_wrong_args(self):
1677 """
Alex Gaynor31287502015-09-05 16:11:27 -04001678 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1679 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001680 """
1681 cert = X509()
1682 self.assertRaises(TypeError, cert.has_expired, None)
1683
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001684 def test_has_expired(self):
1685 """
Alex Gaynor31287502015-09-05 16:11:27 -04001686 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1687 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001688 """
1689 cert = X509()
1690 cert.gmtime_adj_notAfter(-1)
1691 self.assertTrue(cert.has_expired())
1692
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001693 def test_has_not_expired(self):
1694 """
Alex Gaynor31287502015-09-05 16:11:27 -04001695 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1696 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001697 """
1698 cert = X509()
1699 cert.gmtime_adj_notAfter(2)
1700 self.assertFalse(cert.has_expired())
1701
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001702 def test_root_has_not_expired(self):
1703 """
Alex Gaynor31287502015-09-05 16:11:27 -04001704 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1705 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001706 """
1707 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1708 self.assertFalse(cert.has_expired())
1709
Rick Dean38a05c82009-07-18 01:41:30 -05001710 def test_digest(self):
1711 """
Alex Gaynor31287502015-09-05 16:11:27 -04001712 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1713 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001714 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001715 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001716 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001717 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1718 # actually matters to the assertion (ie, another arbitrary, good
1719 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001720 # Digest verified with the command:
1721 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001722 cert.digest("MD5"),
Alex Gaynore7f51982016-09-11 11:48:14 -04001723 b"19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75")
Rick Dean38a05c82009-07-18 01:41:30 -05001724
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001725 def _extcert(self, pkey, extensions):
1726 cert = X509()
1727 cert.set_pubkey(pkey)
1728 cert.get_subject().commonName = "Unit Tests"
1729 cert.get_issuer().commonName = "Unit Tests"
Alex Gaynore7f51982016-09-11 11:48:14 -04001730 when = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001731 cert.set_notBefore(when)
1732 cert.set_notAfter(when)
1733
1734 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001735 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001736 return load_certificate(
1737 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1738
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001739 def test_extension_count(self):
1740 """
Alex Gaynor31287502015-09-05 16:11:27 -04001741 :py:obj:`X509.get_extension_count` returns the number of extensions
1742 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001743 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001744 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Alex Gaynore7f51982016-09-11 11:48:14 -04001745 ca = X509Extension(b'basicConstraints', True, b'CA:FALSE')
1746 key = X509Extension(b'keyUsage', True, b'digitalSignature')
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001747 subjectAltName = X509Extension(
Alex Gaynore7f51982016-09-11 11:48:14 -04001748 b'subjectAltName', True, b'DNS:example.com')
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001749
1750 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001751 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001752 self.assertEqual(c.get_extension_count(), 0)
1753
1754 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001755 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001756 self.assertEqual(c.get_extension_count(), 1)
1757
1758 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001759 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001760 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001761
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001762 def test_get_extension(self):
1763 """
Alex Gaynor31287502015-09-05 16:11:27 -04001764 :py:obj:`X509.get_extension` takes an integer and returns an
1765 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001766 """
1767 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Alex Gaynore7f51982016-09-11 11:48:14 -04001768 ca = X509Extension(b'basicConstraints', True, b'CA:FALSE')
1769 key = X509Extension(b'keyUsage', True, b'digitalSignature')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001770 subjectAltName = X509Extension(
Alex Gaynore7f51982016-09-11 11:48:14 -04001771 b'subjectAltName', False, b'DNS:example.com')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001772
1773 cert = self._extcert(pkey, [ca, key, subjectAltName])
1774
1775 ext = cert.get_extension(0)
1776 self.assertTrue(isinstance(ext, X509Extension))
1777 self.assertTrue(ext.get_critical())
Alex Gaynore7f51982016-09-11 11:48:14 -04001778 self.assertEqual(ext.get_short_name(), b'basicConstraints')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001779
1780 ext = cert.get_extension(1)
1781 self.assertTrue(isinstance(ext, X509Extension))
1782 self.assertTrue(ext.get_critical())
Alex Gaynore7f51982016-09-11 11:48:14 -04001783 self.assertEqual(ext.get_short_name(), b'keyUsage')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001784
1785 ext = cert.get_extension(2)
1786 self.assertTrue(isinstance(ext, X509Extension))
1787 self.assertFalse(ext.get_critical())
Alex Gaynore7f51982016-09-11 11:48:14 -04001788 self.assertEqual(ext.get_short_name(), b'subjectAltName')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001789
1790 self.assertRaises(IndexError, cert.get_extension, -1)
1791 self.assertRaises(IndexError, cert.get_extension, 4)
1792 self.assertRaises(TypeError, cert.get_extension, "hello")
1793
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001794 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001795 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001796 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001797 bytes and this value is reflected in the string representation of the
1798 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001799 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001800 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001801
1802 ext = cert.get_extension(3)
Alex Gaynore7f51982016-09-11 11:48:14 -04001803 self.assertEqual(ext.get_short_name(), b'subjectAltName')
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001804 self.assertEqual(
Alex Gaynore7f51982016-09-11 11:48:14 -04001805 b"DNS:altnull.python.org\x00example.com, "
1806 b"email:null@python.org\x00user@example.org, "
1807 b"URI:http://null.python.org\x00http://example.org, "
1808 b"IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n",
1809 str(ext).encode("ascii"))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001810
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001811 def test_invalid_digest_algorithm(self):
1812 """
Alex Gaynor31287502015-09-05 16:11:27 -04001813 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1814 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001815 """
1816 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001817 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001818
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001819 def test_get_subject_wrong_args(self):
1820 """
Alex Gaynor31287502015-09-05 16:11:27 -04001821 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1822 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001823 """
1824 cert = X509()
1825 self.assertRaises(TypeError, cert.get_subject, None)
1826
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001827 def test_get_subject(self):
1828 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001829 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001830 """
1831 cert = load_certificate(FILETYPE_PEM, self.pemData)
1832 subj = cert.get_subject()
1833 self.assertTrue(isinstance(subj, X509Name))
1834 self.assertEquals(
1835 subj.get_components(),
Alex Gaynore7f51982016-09-11 11:48:14 -04001836 [(b'C', b'US'), (b'ST', b'IL'), (b'L', b'Chicago'),
1837 (b'O', b'Testing'), (b'CN', b'Testing Root CA')])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001838
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001839 def test_set_subject_wrong_args(self):
1840 """
Alex Gaynor31287502015-09-05 16:11:27 -04001841 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1842 the wrong number of arguments or an argument not of type
1843 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001844 """
1845 cert = X509()
1846 self.assertRaises(TypeError, cert.set_subject)
1847 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001848 with pytest.raises(TypeError):
1849 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001850
1851 def test_set_subject(self):
1852 """
Alex Gaynor31287502015-09-05 16:11:27 -04001853 :py:obj:`X509.set_subject` changes the subject of the certificate to
1854 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001855 """
1856 cert = X509()
1857 name = cert.get_subject()
1858 name.C = 'AU'
1859 name.O = 'Unit Tests'
1860 cert.set_subject(name)
1861 self.assertEquals(
1862 cert.get_subject().get_components(),
Alex Gaynore7f51982016-09-11 11:48:14 -04001863 [(b'C', b'AU'), (b'O', b'Unit Tests')])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001864
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001865 def test_get_issuer_wrong_args(self):
1866 """
Alex Gaynor31287502015-09-05 16:11:27 -04001867 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1868 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001869 """
1870 cert = X509()
1871 self.assertRaises(TypeError, cert.get_issuer, None)
1872
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001873 def test_get_issuer(self):
1874 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001875 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001876 """
1877 cert = load_certificate(FILETYPE_PEM, self.pemData)
1878 subj = cert.get_issuer()
1879 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001880 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001881 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001882 comp,
Alex Gaynore7f51982016-09-11 11:48:14 -04001883 [(b'C', b'US'), (b'ST', b'IL'), (b'L', b'Chicago'),
1884 (b'O', b'Testing'), (b'CN', b'Testing Root CA')])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001885
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001886 def test_set_issuer_wrong_args(self):
1887 """
Alex Gaynor31287502015-09-05 16:11:27 -04001888 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1889 the wrong number of arguments or an argument not of type
1890 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001891 """
1892 cert = X509()
1893 self.assertRaises(TypeError, cert.set_issuer)
1894 self.assertRaises(TypeError, cert.set_issuer, None)
1895 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1896
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001897 def test_set_issuer(self):
1898 """
Alex Gaynor31287502015-09-05 16:11:27 -04001899 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1900 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001901 """
1902 cert = X509()
1903 name = cert.get_issuer()
1904 name.C = 'AU'
1905 name.O = 'Unit Tests'
1906 cert.set_issuer(name)
1907 self.assertEquals(
1908 cert.get_issuer().get_components(),
Alex Gaynore7f51982016-09-11 11:48:14 -04001909 [(b'C', b'AU'), (b'O', b'Unit Tests')])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001910
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001911 def test_get_pubkey_uninitialized(self):
1912 """
Alex Gaynor31287502015-09-05 16:11:27 -04001913 When called on a certificate with no public key,
1914 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001915 """
1916 cert = X509()
1917 self.assertRaises(Error, cert.get_pubkey)
1918
Alex Gaynor7778e792016-07-03 23:38:48 -04001919 def test_set_pubkey_wrong_type(self):
1920 """
1921 :obj:`X509.set_pubkey` raises :obj:`TypeError` when given an object of
1922 the wrong type.
1923 """
1924 cert = X509()
1925 with pytest.raises(TypeError):
1926 cert.set_pubkey(object())
1927
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001928 def test_subject_name_hash_wrong_args(self):
1929 """
Alex Gaynor31287502015-09-05 16:11:27 -04001930 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1931 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001932 """
1933 cert = X509()
1934 self.assertRaises(TypeError, cert.subject_name_hash, None)
1935
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001936 def test_subject_name_hash(self):
1937 """
Alex Gaynor31287502015-09-05 16:11:27 -04001938 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1939 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001940 """
1941 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001942 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001943 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001944 [3350047874, # OpenSSL 0.9.8, MD5
1945 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001946 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001947
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001948 def test_get_signature_algorithm(self):
1949 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001950 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001951 the algorithm used to sign the certificate.
1952 """
1953 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001954 self.assertEqual(
Alex Gaynore7f51982016-09-11 11:48:14 -04001955 b"sha1WithRSAEncryption", cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001956
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001957 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001958 """
Alex Gaynor31287502015-09-05 16:11:27 -04001959 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1960 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001961 """
1962 # This certificate has been modified to indicate a bogus OID in the
1963 # signature algorithm field so that OpenSSL does not recognize it.
Alex Gaynore7f51982016-09-11 11:48:14 -04001964 certPEM = b"""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001965-----BEGIN CERTIFICATE-----
1966MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1967EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1968cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1969MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1970EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1971CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1972AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1973+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1974hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1975BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1976FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1977dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1978aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1979MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1980jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1981PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1982tgI5
1983-----END CERTIFICATE-----
Alex Gaynore7f51982016-09-11 11:48:14 -04001984"""
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001985 cert = load_certificate(FILETYPE_PEM, certPEM)
1986 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001987
Alex Gaynor37726112016-07-04 09:51:32 -04001988 def test_sign_bad_pubkey_type(self):
1989 """
1990 :obj:`X509.sign` raises :obj:`TypeError` when called with the wrong
1991 type.
1992 """
1993 cert = X509()
1994 with pytest.raises(TypeError):
1995 cert.sign(object(), b"sha256")
1996
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001997
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001998class X509StoreTests(TestCase):
1999 """
2000 Test for :py:obj:`OpenSSL.crypto.X509Store`.
2001 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002002
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002003 def test_type(self):
2004 """
2005 :py:obj:`X509StoreType` is a type object.
2006 """
2007 self.assertIdentical(X509Store, X509StoreType)
2008 self.assertConsistentType(X509Store, 'X509Store')
2009
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002010 def test_add_cert_wrong_args(self):
2011 store = X509Store()
2012 self.assertRaises(TypeError, store.add_cert)
2013 self.assertRaises(TypeError, store.add_cert, object())
2014 self.assertRaises(TypeError, store.add_cert, X509(), object())
2015
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002016 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002017 """
2018 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
2019 certificate store.
2020 """
2021 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002022 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002023 store.add_cert(cert)
2024
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002025 def test_add_cert_rejects_duplicate(self):
2026 """
Alex Gaynor31287502015-09-05 16:11:27 -04002027 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
2028 an attempt is made to add the same certificate to the store more than
2029 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08002030 """
2031 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2032 store = X509Store()
2033 store.add_cert(cert)
2034 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08002035
2036
Rick Dean623ee362009-07-17 12:22:16 -05002037class PKCS12Tests(TestCase):
2038 """
Alex Gaynor31287502015-09-05 16:11:27 -04002039 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
2040 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002041 """
2042 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
2043
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002044 def test_type(self):
2045 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002046 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04002047 """
2048 self.assertIdentical(PKCS12, PKCS12Type)
2049 self.assertConsistentType(PKCS12, 'PKCS12')
2050
Rick Deanf94096c2009-07-18 14:23:06 -05002051 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002052 """
Alex Gaynor31287502015-09-05 16:11:27 -04002053 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
2054 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05002055 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002056 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05002057 self.assertEqual(None, p12.get_certificate())
2058 self.assertEqual(None, p12.get_privatekey())
2059 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05002060 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05002061
2062 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05002063 """
Alex Gaynor31287502015-09-05 16:11:27 -04002064 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
2065 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
2066 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
2067 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05002068 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002069 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05002070 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002071 self.assertRaises(TypeError, p12.set_certificate, PKey())
2072 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05002073 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05002074 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
2075 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05002076 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
2077 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
2078 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04002079 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05002080 self.assertRaises(TypeError, p12.set_friendlyname, 6)
2081 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05002082
2083 def test_key_only(self):
2084 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002085 A :py:obj:`PKCS12` with only a private key can be exported using
2086 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002087 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002088 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002089 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002090 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002091 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05002092 self.assertEqual(None, p12.get_certificate())
2093 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002094 try:
2095 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2096 except Error:
2097 # Some versions of OpenSSL will throw an exception
2098 # for this nearly useless PKCS12 we tried to generate:
2099 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2100 return
Rick Dean623ee362009-07-17 12:22:16 -05002101 p12 = load_pkcs12(dumped_p12, passwd)
2102 self.assertEqual(None, p12.get_ca_certificates())
2103 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002104
2105 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
2106 # future this will be improved.
2107 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05002108
2109 def test_cert_only(self):
2110 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002111 A :py:obj:`PKCS12` with only a certificate can be exported using
2112 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05002113 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002114 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05002115 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002116 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002117 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05002118 self.assertEqual(cert, p12.get_certificate())
2119 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05002120 try:
2121 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
2122 except Error:
2123 # Some versions of OpenSSL will throw an exception
2124 # for this nearly useless PKCS12 we tried to generate:
2125 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
2126 return
Rick Dean623ee362009-07-17 12:22:16 -05002127 p12 = load_pkcs12(dumped_p12, passwd)
2128 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002129
2130 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
2131 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2132
2133 # Oh ho. It puts the certificate into the ca certificates list, in
2134 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2135 # that to check to see if it reconstructed the certificate we expected
2136 # it to. At some point, hopefully this will change so that
2137 # p12.get_certificate() is actually what returns the loaded
2138 # certificate.
2139 self.assertEqual(
2140 cleartextCertificatePEM,
2141 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002142
Alex Gaynor31287502015-09-05 16:11:27 -04002143 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2144 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002145 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002146 Generate a PKCS12 object with components from PEM. Verify that the set
2147 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002148 """
Rick Deanf94096c2009-07-18 14:23:06 -05002149 p12 = PKCS12()
2150 if cert_pem:
2151 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2152 self.assertEqual(ret, None)
2153 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002154 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002155 self.assertEqual(ret, None)
2156 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002157 ret = p12.set_ca_certificates(
2158 (load_certificate(FILETYPE_PEM, ca_pem),)
2159 )
Rick Deanf94096c2009-07-18 14:23:06 -05002160 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002161 if friendly_name:
2162 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002163 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002164 return p12
2165
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002166 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002167 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002168 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002169 Use openssl program to confirm three components are recoverable from a
2170 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002171 """
2172 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002173 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002174 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2175 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002176 self.assertEqual(recovered_key[-len(key):], key)
2177 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002178 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002179 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2180 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002181 self.assertEqual(recovered_cert[-len(cert):], cert)
2182 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002183 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002184 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2185 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002186 self.assertEqual(recovered_cert[-len(ca):], ca)
2187
Stephen Holsapple38482622014-04-05 20:29:34 -07002188 def verify_pkcs12_container(self, p12):
2189 """
2190 Verify that the PKCS#12 container contains the correct client
2191 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002192
2193 :param p12: The PKCS12 instance to verify.
2194 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002195 """
2196 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2197 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002198 self.assertEqual(
2199 (client_cert_pem, client_key_pem, None),
2200 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002201
Rick Deanf94096c2009-07-18 14:23:06 -05002202 def test_load_pkcs12(self):
2203 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002204 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002205 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002206 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002207 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002208 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002209 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002210 pem,
2211 b"pkcs12",
2212 b"-export",
2213 b"-clcerts",
2214 b"-passout",
2215 b"pass:" + passwd
2216 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002217 p12 = load_pkcs12(p12_str, passphrase=passwd)
2218 self.verify_pkcs12_container(p12)
2219
Abraham Martinc5484ba2015-03-25 15:33:05 +00002220 def test_load_pkcs12_text_passphrase(self):
2221 """
2222 A PKCS12 string generated using the openssl command line can be loaded
2223 with :py:obj:`load_pkcs12` and its components extracted and examined.
2224 Using text as passphrase instead of bytes. DeprecationWarning expected.
2225 """
2226 pem = client_key_pem + client_cert_pem
2227 passwd = b"whatever"
2228 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2229 b"-passout", b"pass:" + passwd)
2230 with catch_warnings(record=True) as w:
2231 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002232 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002233
2234 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002235 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002236 WARNING_TYPE_EXPECTED
2237 ),
2238 str(w[-1].message)
2239 )
2240 self.assertIs(w[-1].category, DeprecationWarning)
2241
Abraham Martinc5484ba2015-03-25 15:33:05 +00002242 self.verify_pkcs12_container(p12)
2243
Stephen Holsapple38482622014-04-05 20:29:34 -07002244 def test_load_pkcs12_no_passphrase(self):
2245 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002246 A PKCS12 string generated using openssl command line can be loaded with
2247 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2248 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002249 """
2250 pem = client_key_pem + client_cert_pem
2251 p12_str = _runopenssl(
2252 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2253 p12 = load_pkcs12(p12_str)
2254 self.verify_pkcs12_container(p12)
2255
Stephen Holsapple38482622014-04-05 20:29:34 -07002256 def _dump_and_load(self, dump_passphrase, load_passphrase):
2257 """
2258 A helper method to dump and load a PKCS12 object.
2259 """
2260 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2261 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2262 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2263
Stephen Holsapple38482622014-04-05 20:29:34 -07002264 def test_load_pkcs12_null_passphrase_load_empty(self):
2265 """
2266 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002267 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002268 extracted and examined.
2269 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002270 self.verify_pkcs12_container(
2271 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002272
Stephen Holsapple38482622014-04-05 20:29:34 -07002273 def test_load_pkcs12_null_passphrase_load_null(self):
2274 """
2275 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002276 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002277 extracted and examined.
2278 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002279 self.verify_pkcs12_container(
2280 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002281
Stephen Holsapple38482622014-04-05 20:29:34 -07002282 def test_load_pkcs12_empty_passphrase_load_empty(self):
2283 """
2284 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002285 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002286 extracted and examined.
2287 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002288 self.verify_pkcs12_container(
2289 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002290
Stephen Holsapple38482622014-04-05 20:29:34 -07002291 def test_load_pkcs12_empty_passphrase_load_null(self):
2292 """
2293 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002294 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002295 extracted and examined.
2296 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002297 self.verify_pkcs12_container(
2298 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002299
Rick Deanee568302009-07-24 09:56:29 -05002300 def test_load_pkcs12_garbage(self):
2301 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002302 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2303 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002304 """
2305 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002306 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002307 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2308 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002309
Rick Deanf94096c2009-07-18 14:23:06 -05002310 def test_replace(self):
2311 """
Alex Gaynor31287502015-09-05 16:11:27 -04002312 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2313 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002314 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002315 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002316 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2317 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2318 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002319 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002320 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002321 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002322 self.assertEqual(1, len(p12.get_ca_certificates()))
2323 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002324 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002325 self.assertEqual(2, len(p12.get_ca_certificates()))
2326 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2327 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2328
Rick Deanf94096c2009-07-18 14:23:06 -05002329 def test_friendly_name(self):
2330 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002331 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002332 :py:obj:`PKCS12.get_friendlyname` and
2333 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2334 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002335 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002336 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002337 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Alex Gaynore7f51982016-09-11 11:48:14 -04002338 for friendly_name in [b'Serverlicious', None, b'###']:
Rick Dean42d69e12009-07-20 11:36:08 -05002339 p12.set_friendlyname(friendly_name)
2340 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002341 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002342 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002343 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002344 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002345 # We would use the openssl program to confirm the friendly
2346 # name, but it is not possible. The pkcs12 command
2347 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002348 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002349 self.check_recovery(
2350 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2351 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002352
Rick Deanf94096c2009-07-18 14:23:06 -05002353 def test_various_empty_passphrases(self):
2354 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002355 Test that missing, None, and '' passphrases are identical for PKCS12
2356 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002357 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002358 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002359 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002360 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2361 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2362 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2363 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2364 self.check_recovery(
2365 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2366 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002367
Rick Deanf94096c2009-07-18 14:23:06 -05002368 def test_removing_ca_cert(self):
2369 """
Alex Gaynor31287502015-09-05 16:11:27 -04002370 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2371 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002372 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002373 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2374 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002375 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002376
Rick Deanf94096c2009-07-18 14:23:06 -05002377 def test_export_without_mac(self):
2378 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002379 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002380 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002381 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002382 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002383 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002384 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002385 self.check_recovery(
2386 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002387 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002388
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002389 def test_load_without_mac(self):
2390 """
2391 Loading a PKCS12 without a MAC does something other than crash.
2392 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002393 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002394 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2395 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002396 try:
2397 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2398 # The person who generated this PCKS12 should be flogged,
2399 # or better yet we should have a means to determine
2400 # whether a PCKS12 had a MAC that was verified.
2401 # Anyway, libopenssl chooses to allow it, so the
2402 # pyopenssl binding does as well.
2403 self.assertTrue(isinstance(recovered_p12, PKCS12))
2404 except Error:
2405 # Failing here with an exception is preferred as some openssl
2406 # versions do.
2407 pass
Rick Dean623ee362009-07-17 12:22:16 -05002408
Rick Dean25bcc1f2009-07-20 11:53:13 -05002409 def test_zero_len_list_for_ca(self):
2410 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002411 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002412 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002413 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002414 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002415 p12.set_ca_certificates([])
2416 self.assertEqual((), p12.get_ca_certificates())
2417 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2418 self.check_recovery(
2419 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2420 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002421
Rick Deanf94096c2009-07-18 14:23:06 -05002422 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002423 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002424 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002425 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002426 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002427 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002428 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002429 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002430
Abraham Martinc5484ba2015-03-25 15:33:05 +00002431 def test_export_without_bytes(self):
2432 """
2433 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2434 """
2435 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2436
2437 with catch_warnings(record=True) as w:
2438 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002439 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002440 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002441 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002442 WARNING_TYPE_EXPECTED
2443 ),
2444 str(w[-1].message)
2445 )
2446 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002447 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002448 dumped_p12,
2449 key=server_key_pem,
2450 cert=server_cert_pem,
2451 passwd=b"randomtext"
2452 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002453
Rick Deanf94096c2009-07-18 14:23:06 -05002454 def test_key_cert_mismatch(self):
2455 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002456 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002457 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002458 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002459 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2460 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002461
2462
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002463# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002464_cmdLineQuoteRe = re.compile(br'(\\*)"')
2465_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002466
2467
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002468def cmdLineQuote(s):
2469 """
2470 Internal method for quoting a single command-line argument.
2471
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002472 See http://www.perlmonks.org/?node_id=764004
2473
Jonathan Ballet648875f2011-07-16 14:14:58 +09002474 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002475 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002476 cmd.exe-style quoting
2477
Jonathan Ballet648875f2011-07-16 14:14:58 +09002478 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002479 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002480 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002481 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2482 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002483
2484
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002485def quoteArguments(arguments):
2486 """
2487 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002488 a similar API. This allows the list passed to
2489 :py:obj:`reactor.spawnProcess` to match the child process's
2490 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002491
Jonathan Ballet648875f2011-07-16 14:14:58 +09002492 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002493 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002494
Jonathan Ballet648875f2011-07-16 14:14:58 +09002495 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002496 :return: A space-delimited string containing quoted versions of
2497 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002498 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002499 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002500
2501
Rick Dean4c9ad612009-07-17 15:05:22 -05002502def _runopenssl(pem, *args):
2503 """
2504 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002505 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002506 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002507 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002508 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002509 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2510 for arg in args
2511 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002512 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002513 command = b"openssl " + quoteArguments(args)
2514 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002515 proc.stdin.write(pem)
2516 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002517 output = proc.stdout.read()
2518 proc.stdout.close()
2519 proc.wait()
2520 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002521
2522
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002523class TestLoadPublicKey(object):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002524 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002525 Tests for :func:`load_publickey`.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002526 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002527 def test_loading_works(self):
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002528 """
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002529 load_publickey loads public keys and sets correct attributes.
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002530 """
2531 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002532
2533 assert True is key._only_public
2534 assert 2048 == key.bits()
2535 assert TYPE_RSA == key.type()
2536
2537 def test_invalid_type(self):
2538 """
2539 load_publickey doesn't support FILETYPE_TEXT.
2540 """
2541 with pytest.raises(ValueError):
2542 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2543
2544 def test_invalid_key_format(self):
2545 """
2546 load_publickey explodes on incorrect keys.
2547 """
2548 with pytest.raises(Error):
2549 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2550
2551 def test_tolerates_unicode_strings(self):
2552 """
2553 load_publickey works with text strings, not just bytes.
2554 """
2555 serialized = cleartextPublicKeyPEM.decode('ascii')
2556 key = load_publickey(FILETYPE_PEM, serialized)
2557 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2558
2559 assert dumped_pem == cleartextPublicKeyPEM
Paul Kehrer32fc4e62016-06-03 15:21:44 -07002560
2561
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002562class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002563 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002564 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Hynek Schlawack40d448f2016-06-03 16:15:14 -07002565
2566 Add new tests to `TestFunctions` above.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002567 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002568
2569 def test_load_privatekey_invalid_format(self):
2570 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002571 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2572 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002573 """
2574 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2575
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002576 def test_load_privatekey_invalid_passphrase_type(self):
2577 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002578 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2579 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002580 """
2581 self.assertRaises(
2582 TypeError,
2583 load_privatekey,
2584 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2585
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002586 def test_load_privatekey_wrong_args(self):
2587 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002588 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2589 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002590 """
2591 self.assertRaises(TypeError, load_privatekey)
2592
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002593 def test_load_privatekey_wrongPassphrase(self):
2594 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002595 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2596 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002597 """
2598 self.assertRaises(
2599 Error,
Alex Gaynore7f51982016-09-11 11:48:14 -04002600 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b"quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002601
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002602 def test_load_privatekey_passphraseWrongType(self):
2603 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002604 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2605 a passphrase with a private key encoded in a format, that doesn't
2606 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002607 """
2608 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2609 blob = dump_privatekey(FILETYPE_ASN1, key)
2610 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002611 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002612
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002613 def test_load_privatekey_passphrase(self):
2614 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002615 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2616 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002617 """
2618 key = load_privatekey(
2619 FILETYPE_PEM, encryptedPrivateKeyPEM,
2620 encryptedPrivateKeyPEMPassphrase)
2621 self.assertTrue(isinstance(key, PKeyType))
2622
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002623 def test_load_privatekey_passphrase_exception(self):
2624 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002625 If the passphrase callback raises an exception, that exception is
2626 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002627 """
2628 def cb(ignored):
2629 raise ArithmeticError
2630
Alex Gaynor791212d2015-09-05 15:46:08 -04002631 with pytest.raises(ArithmeticError):
2632 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002633
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002634 def test_load_privatekey_wrongPassphraseCallback(self):
2635 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002636 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2637 is passed an encrypted PEM and a passphrase callback which returns an
2638 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002639 """
2640 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002641
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002642 def cb(*a):
2643 called.append(None)
Alex Gaynore7f51982016-09-11 11:48:14 -04002644 return b"quack"
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002645 self.assertRaises(
2646 Error,
2647 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2648 self.assertTrue(called)
2649
2650 def test_load_privatekey_passphraseCallback(self):
2651 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002652 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2653 encrypted PEM string if given a passphrase callback which returns the
2654 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002655 """
2656 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002657
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002658 def cb(writing):
2659 called.append(writing)
2660 return encryptedPrivateKeyPEMPassphrase
2661 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2662 self.assertTrue(isinstance(key, PKeyType))
2663 self.assertEqual(called, [False])
2664
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002665 def test_load_privatekey_passphrase_wrong_return_type(self):
2666 """
2667 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2668 callback returns something other than a byte string.
2669 """
2670 self.assertRaises(
2671 ValueError,
2672 load_privatekey,
2673 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2674
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002675 def test_dump_privatekey_wrong_args(self):
2676 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002677 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2678 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002679 """
2680 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002681 # If cipher name is given, password is required.
2682 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002683 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002684
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002685 def test_dump_privatekey_unknown_cipher(self):
2686 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002687 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2688 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002689 """
2690 key = PKey()
2691 key.generate_key(TYPE_RSA, 512)
2692 self.assertRaises(
2693 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002694 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002695
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002696 def test_dump_privatekey_invalid_passphrase_type(self):
2697 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002698 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2699 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002700 """
2701 key = PKey()
2702 key.generate_key(TYPE_RSA, 512)
2703 self.assertRaises(
2704 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002705 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002706
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002707 def test_dump_privatekey_invalid_filetype(self):
2708 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002709 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2710 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002711 """
2712 key = PKey()
2713 key.generate_key(TYPE_RSA, 512)
2714 self.assertRaises(ValueError, dump_privatekey, 100, key)
2715
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002716 def test_load_privatekey_passphraseCallbackLength(self):
2717 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002718 :py:obj:`crypto.load_privatekey` should raise an error when the
2719 passphrase provided by the callback is too long, not silently truncate
2720 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002721 """
2722 def cb(ignored):
2723 return "a" * 1025
2724
Alex Gaynor791212d2015-09-05 15:46:08 -04002725 with pytest.raises(ValueError):
2726 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002727
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002728 def test_dump_privatekey_passphrase(self):
2729 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002730 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2731 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002732 """
Alex Gaynore7f51982016-09-11 11:48:14 -04002733 passphrase = b"foo"
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002734 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002735 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2736 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002737 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2738 self.assertTrue(isinstance(loadedKey, PKeyType))
2739 self.assertEqual(loadedKey.type(), key.type())
2740 self.assertEqual(loadedKey.bits(), key.bits())
2741
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002742 def test_dump_privatekey_passphraseWrongType(self):
2743 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002744 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2745 a passphrase with a private key encoded in a format, that doesn't
2746 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002747 """
2748 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002749 with pytest.raises(ValueError):
2750 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002751
Rick Dean5b7b6372009-04-01 11:34:06 -05002752 def test_dump_certificate(self):
2753 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002754 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002755 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002756 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002757 cert = load_certificate(FILETYPE_PEM, pemData)
2758 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2759 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2760 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002761 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002762 self.assertEqual(dumped_der, good_der)
2763 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2764 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2765 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2766 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Alex Gaynor316aa2c2016-09-10 14:42:53 -04002767 good_text = _runopenssl(
2768 dumped_pem, b"x509", b"-noout", b"-text", b"-nameopt", b"")
Rick Dean5b7b6372009-04-01 11:34:06 -05002769 self.assertEqual(dumped_text, good_text)
2770
Alex Gaynor37726112016-07-04 09:51:32 -04002771 def test_dump_certificate_bad_type(self):
2772 """
2773 :obj:`dump_certificate` raises a :obj:`ValueError` if it's called with
2774 a bad type.
2775 """
2776 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2777 with pytest.raises(ValueError):
2778 dump_certificate(object(), cert)
2779
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002780 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002781 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002782 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002783 """
2784 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002785 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002786 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2787 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002788
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002789 def test_dump_privatekey_asn1(self):
2790 """
2791 :py:obj:`dump_privatekey` writes a DER
2792 """
2793 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2794 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2795
Rick Dean5b7b6372009-04-01 11:34:06 -05002796 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002797 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002798 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002799 self.assertEqual(dumped_der, good_der)
2800 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2801 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2802 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002803
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002804 def test_dump_privatekey_text(self):
2805 """
2806 :py:obj:`dump_privatekey` writes a text
2807 """
2808 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2809 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2810
Rick Dean5b7b6372009-04-01 11:34:06 -05002811 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002812 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002813 self.assertEqual(dumped_text, good_text)
2814
Cory Benfield6492f7c2015-10-27 16:57:58 +09002815 def test_dump_publickey_pem(self):
2816 """
Cory Benfield11c10192015-10-27 17:23:03 +09002817 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002818 """
2819 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2820 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002821 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002822
2823 def test_dump_publickey_asn1(self):
2824 """
Cory Benfield11c10192015-10-27 17:23:03 +09002825 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002826 """
2827 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2828 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2829 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2830 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002831 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002832
Cory Benfielde02c7d82015-10-27 17:34:49 +09002833 def test_dump_publickey_invalid_type(self):
2834 """
2835 dump_publickey doesn't support FILETYPE_TEXT.
2836 """
2837 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2838
2839 with pytest.raises(ValueError):
2840 dump_publickey(FILETYPE_TEXT, key)
2841
Rick Dean5b7b6372009-04-01 11:34:06 -05002842 def test_dump_certificate_request(self):
2843 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002844 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002845 """
Alex Gaynor31287502015-09-05 16:11:27 -04002846 req = load_certificate_request(
2847 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002848 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2849 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2850 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002851 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002852 self.assertEqual(dumped_der, good_der)
2853 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2854 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2855 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2856 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Alex Gaynor316aa2c2016-09-10 14:42:53 -04002857 good_text = _runopenssl(
2858 dumped_pem, b"req", b"-noout", b"-text", b"-nameopt", b"")
Rick Dean5b7b6372009-04-01 11:34:06 -05002859 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002860 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002861
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002862 def test_dump_privatekey_passphraseCallback(self):
2863 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002864 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2865 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002866 """
Alex Gaynore7f51982016-09-11 11:48:14 -04002867 passphrase = b"foo"
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002868 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002869
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002870 def cb(writing):
2871 called.append(writing)
2872 return passphrase
2873 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002874 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2875 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002876 self.assertEqual(called, [True])
2877 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2878 self.assertTrue(isinstance(loadedKey, PKeyType))
2879 self.assertEqual(loadedKey.type(), key.type())
2880 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002881
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002882 def test_dump_privatekey_passphrase_exception(self):
2883 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002884 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002885 by the passphrase callback.
2886 """
2887 def cb(ignored):
2888 raise ArithmeticError
2889
2890 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002891 with pytest.raises(ArithmeticError):
2892 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002893
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002894 def test_dump_privatekey_passphraseCallbackLength(self):
2895 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002896 :py:obj:`crypto.dump_privatekey` should raise an error when the
2897 passphrase provided by the callback is too long, not silently truncate
2898 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002899 """
2900 def cb(ignored):
2901 return "a" * 1025
2902
2903 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002904 with pytest.raises(ValueError):
2905 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002906
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002907 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002908 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002909 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2910 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002911 """
2912 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2913 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2914
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002915 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002916 """
2917 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2918 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2919 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002920 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2921 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2922
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002923 def test_load_pkcs7_data_invalid(self):
2924 """
2925 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2926 :py:obj:`Error` is raised.
2927 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002928 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002929
Alex Gaynor09a386e2016-07-03 09:32:44 -04002930 def test_load_pkcs7_type_invalid(self):
2931 """
2932 If the type passed to :obj:`load_pkcs7_data`, :obj:`ValueError` is
2933 raised.
2934 """
2935 with pytest.raises(ValueError):
2936 load_pkcs7_data(object(), b"foo")
2937
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002938
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002939class LoadCertificateTests(TestCase):
2940 """
2941 Tests for :py:obj:`load_certificate_request`.
2942 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002943
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002944 def test_badFileType(self):
2945 """
2946 If the file type passed to :py:obj:`load_certificate_request` is
2947 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2948 :py:class:`ValueError` is raised.
2949 """
Alex Gaynor7778e792016-07-03 23:38:48 -04002950 with pytest.raises(ValueError):
2951 load_certificate_request(object(), b"")
2952 with pytest.raises(ValueError):
2953 load_certificate(object(), b"")
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002954
Alex Gaynor37726112016-07-04 09:51:32 -04002955 def test_bad_certificate(self):
2956 """
2957 If the bytes passed to :obj:`load_certificate` are not a valid
2958 certificate, an exception is raised.
2959 """
2960 with pytest.raises(Error):
2961 load_certificate(FILETYPE_ASN1, b"lol")
2962
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002963
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002964class PKCS7Tests(TestCase):
2965 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002966 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002967 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002968
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002969 def test_type(self):
2970 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002971 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002972 """
2973 self.assertTrue(isinstance(PKCS7Type, type))
2974 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2975
2976 # XXX This doesn't currently work.
2977 # self.assertIdentical(PKCS7, PKCS7Type)
2978
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002979 # XXX Opposite results for all these following methods
2980
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002981 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002982 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002983 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2984 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002985 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002986 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2987 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2988
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002989 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002990 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002991 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2992 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002993 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002994 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2995 self.assertTrue(pkcs7.type_is_signed())
2996
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002997 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002998 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002999 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
3000 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003001 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003002 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3003 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
3004
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003005 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003006 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003007 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
3008 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003009 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003010 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3011 self.assertFalse(pkcs7.type_is_enveloped())
3012
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003013 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003014 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003015 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
3016 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003017 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003018 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3019 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
3020
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003021 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003022 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003023 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
3024 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003025 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04003026 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3027 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
3028
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003029 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003030 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003031 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
3032 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003033 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003034 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3035 self.assertFalse(pkcs7.type_is_data())
3036
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003037 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003038 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003039 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
3040 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003041 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04003042 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3043 self.assertRaises(TypeError, pkcs7.type_is_data, None)
3044
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003045 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003046 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003047 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
3048 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003049 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04003050 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3051 self.assertRaises(TypeError, pkcs7.get_type_name, None)
3052
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003053 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003054 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003055 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
3056 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003057 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003058 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Alex Gaynore7f51982016-09-11 11:48:14 -04003059 self.assertEquals(pkcs7.get_type_name(), b'pkcs7-signedData')
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003060
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003061 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003062 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003063 If an attribute other than one of the methods tested here is accessed
3064 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
3065 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04003066 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04003067 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
3068 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
3069
3070
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003071class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003072 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003073 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003074 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003075
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003076 def signable(self):
3077 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003078 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04003079 """
3080 return NetscapeSPKI()
3081
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003082 def test_type(self):
3083 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003084 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
3085 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04003086 """
3087 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
3088 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
3089
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003090 def test_construction(self):
3091 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003092 :py:obj:`NetscapeSPKI` returns an instance of
3093 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003094 """
3095 nspki = NetscapeSPKI()
3096 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
3097
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003098 def test_invalid_attribute(self):
3099 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003100 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
3101 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04003102 """
3103 nspki = NetscapeSPKI()
3104 self.assertRaises(AttributeError, lambda: nspki.foo)
3105
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003106 def test_b64_encode(self):
3107 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003108 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
3109 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003110 """
3111 nspki = NetscapeSPKI()
3112 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003113 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04003114
3115
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003116class TestRevoked(object):
3117 """
3118 Please add test cases for the Revoked class here if possible. This class
3119 holds the new py.test style tests.
3120 """
3121 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3122 """
3123 The get_reason method on the Revoked class checks to see if the
3124 extension is NID_crl_reason and should skip it otherwise. This test
3125 loads a CRL with extensions it should ignore.
3126 """
3127 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3128 revoked = crl.get_revoked()
3129 reason = revoked[1].get_reason()
3130 assert reason == b'Unspecified'
3131
3132 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3133 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3134 revoked = crl.get_revoked()
3135 revoked[1].set_reason(None)
3136 reason = revoked[1].get_reason()
3137 assert reason is None
3138
3139
Rick Dean536ba022009-07-24 23:57:27 -05003140class RevokedTests(TestCase):
3141 """
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003142 Tests for :py:obj:`OpenSSL.crypto.Revoked`. Please add test cases to
3143 TestRevoked above if possible.
Rick Dean536ba022009-07-24 23:57:27 -05003144 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003145
Rick Dean536ba022009-07-24 23:57:27 -05003146 def test_construction(self):
3147 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003148 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003149 that it is empty.
3150 """
3151 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003152 self.assertTrue(isinstance(revoked, Revoked))
3153 self.assertEquals(type(revoked), Revoked)
Alex Gaynore7f51982016-09-11 11:48:14 -04003154 self.assertEquals(revoked.get_serial(), b'00')
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003155 self.assertEquals(revoked.get_rev_date(), None)
3156 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05003157
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003158 def test_construction_wrong_args(self):
3159 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003160 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
3161 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003162 """
3163 self.assertRaises(TypeError, Revoked, None)
3164 self.assertRaises(TypeError, Revoked, 1)
3165 self.assertRaises(TypeError, Revoked, "foo")
3166
Rick Dean536ba022009-07-24 23:57:27 -05003167 def test_serial(self):
3168 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003169 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003170 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003171 with grace.
3172 """
3173 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003174 ret = revoked.set_serial(b'10b')
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003175 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003176 ser = revoked.get_serial()
Alex Gaynore7f51982016-09-11 11:48:14 -04003177 self.assertEquals(ser, b'010B')
Rick Dean536ba022009-07-24 23:57:27 -05003178
Alex Gaynore7f51982016-09-11 11:48:14 -04003179 revoked.set_serial(b'31ppp') # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003180 ser = revoked.get_serial()
Alex Gaynore7f51982016-09-11 11:48:14 -04003181 self.assertEquals(ser, b'31')
Rick Dean536ba022009-07-24 23:57:27 -05003182
Alex Gaynore7f51982016-09-11 11:48:14 -04003183 self.assertRaises(ValueError, revoked.set_serial, b'pqrst')
Rick Dean536ba022009-07-24 23:57:27 -05003184 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003185 self.assertRaises(TypeError, revoked.get_serial, 1)
3186 self.assertRaises(TypeError, revoked.get_serial, None)
3187 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05003188
Rick Dean536ba022009-07-24 23:57:27 -05003189 def test_date(self):
3190 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003191 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003192 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05003193 with grace.
3194 """
3195 revoked = Revoked()
3196 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003197 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05003198
Alex Gaynore7f51982016-09-11 11:48:14 -04003199 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003200 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003201 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05003202 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003203 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05003204
Rick Dean6385faf2009-07-26 00:07:47 -05003205 def test_reason(self):
3206 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003207 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003208 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003209 as "set". Likewise, each reason of all_reasons() must work.
3210 """
3211 revoked = Revoked()
3212 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003213 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003214 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003215 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003216 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003217 self.assertEquals(
Alex Gaynore7f51982016-09-11 11:48:14 -04003218 reason.lower().replace(b' ', b''),
3219 r.lower().replace(b' ', b''))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003220 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003221
3222 revoked.set_reason(None)
3223 self.assertEqual(revoked.get_reason(), None)
3224
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003225 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003226 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003227 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003228 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003229 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003230 """
3231 revoked = Revoked()
3232 self.assertRaises(TypeError, revoked.set_reason, 100)
Alex Gaynore7f51982016-09-11 11:48:14 -04003233 self.assertRaises(ValueError, revoked.set_reason, b'blue')
Rick Dean6385faf2009-07-26 00:07:47 -05003234
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003235 def test_get_reason_wrong_arguments(self):
3236 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003237 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3238 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003239 """
3240 revoked = Revoked()
3241 self.assertRaises(TypeError, revoked.get_reason, None)
3242 self.assertRaises(TypeError, revoked.get_reason, 1)
3243 self.assertRaises(TypeError, revoked.get_reason, "foo")
3244
3245
Rick Dean536ba022009-07-24 23:57:27 -05003246class CRLTests(TestCase):
3247 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003248 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003249 """
3250 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3251 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3252
Dan Sully44e767a2016-06-04 18:05:27 -07003253 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3254 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3255 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3256 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3257 intermediate_server_cert = load_certificate(
3258 FILETYPE_PEM, intermediate_server_cert_pem)
3259 intermediate_server_key = load_privatekey(
3260 FILETYPE_PEM, intermediate_server_key_pem)
3261
Rick Dean536ba022009-07-24 23:57:27 -05003262 def test_construction(self):
3263 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003264 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003265 that it is empty
3266 """
3267 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003268 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003269 self.assertEqual(crl.get_revoked(), None)
3270
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003271 def test_construction_wrong_args(self):
3272 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003273 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3274 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003275 """
3276 self.assertRaises(TypeError, CRL, 1)
3277 self.assertRaises(TypeError, CRL, "")
3278 self.assertRaises(TypeError, CRL, None)
3279
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003280 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003281 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003282 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003283 """
3284 crl = CRL()
3285 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003286 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003287 revoked.set_rev_date(now)
Alex Gaynore7f51982016-09-11 11:48:14 -04003288 revoked.set_serial(b'3ab')
3289 revoked.set_reason(b'sUpErSeDEd')
Rick Dean536ba022009-07-24 23:57:27 -05003290 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003291 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003292
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003293 def test_export_pem(self):
3294 """
3295 If not passed a format, ``CRL.export`` returns a "PEM" format string
3296 representing a serial number, a revoked reason, and certificate issuer
3297 information.
3298 """
3299 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003300 # PEM format
3301 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003302 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003303
3304 # These magic values are based on the way the CRL above was constructed
3305 # and with what certificate it was exported.
Alex Gaynore7f51982016-09-11 11:48:14 -04003306 text.index(b'Serial Number: 03AB')
3307 text.index(b'Superseded')
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003308 text.index(
Alex Gaynore7f51982016-09-11 11:48:14 -04003309 b'Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA'
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003310 )
3311
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003312 def test_export_der(self):
3313 """
3314 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3315 "DER" format string representing a serial number, a revoked reason, and
3316 certificate issuer information.
3317 """
3318 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003319
3320 # DER format
3321 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003322 text = _runopenssl(
3323 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3324 )
Alex Gaynore7f51982016-09-11 11:48:14 -04003325 text.index(b'Serial Number: 03AB')
3326 text.index(b'Superseded')
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003327 text.index(
Alex Gaynore7f51982016-09-11 11:48:14 -04003328 b'Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA'
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003329 )
3330
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003331 def test_export_text(self):
3332 """
3333 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3334 text format string like the one produced by the openssl command line
3335 tool.
3336 """
3337 crl = self._get_crl()
3338
3339 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3340 text = _runopenssl(
3341 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3342 )
Rick Dean536ba022009-07-24 23:57:27 -05003343
3344 # text format
3345 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3346 self.assertEqual(text, dumped_text)
3347
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003348 def test_export_custom_digest(self):
3349 """
3350 If passed the name of a digest function, ``CRL.export`` uses a
3351 signature algorithm based on that digest function.
3352 """
3353 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003354 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003355 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynore7f51982016-09-11 11:48:14 -04003356 text.index(b'Signature Algorithm: sha1')
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003357
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003358 def test_export_md5_digest(self):
3359 """
3360 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3361 not emit a deprecation warning.
3362 """
3363 crl = self._get_crl()
3364 with catch_warnings(record=True) as catcher:
3365 simplefilter("always")
3366 self.assertEqual(0, len(catcher))
3367 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3368 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynore7f51982016-09-11 11:48:14 -04003369 text.index(b'Signature Algorithm: md5')
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003370
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003371 def test_export_default_digest(self):
3372 """
3373 If not passed the name of a digest function, ``CRL.export`` uses a
3374 signature algorithm based on MD5 and emits a deprecation warning.
3375 """
3376 crl = self._get_crl()
3377 with catch_warnings(record=True) as catcher:
3378 simplefilter("always")
3379 dumped_crl = crl.export(self.cert, self.pkey)
3380 self.assertEqual(
3381 "The default message digest (md5) is deprecated. "
3382 "Pass the name of a message digest explicitly.",
3383 str(catcher[0].message),
3384 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003385 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynore7f51982016-09-11 11:48:14 -04003386 text.index(b'Signature Algorithm: md5')
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003387
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003388 def test_export_invalid(self):
3389 """
3390 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003391 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003392 """
3393 crl = CRL()
3394 self.assertRaises(Error, crl.export, X509(), PKey())
3395
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003396 def test_add_revoked_keyword(self):
3397 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003398 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003399 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003400 """
3401 crl = CRL()
3402 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003403 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003404 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003405 crl.add_revoked(revoked=revoked)
3406 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3407
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003408 def test_export_wrong_args(self):
3409 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003410 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003411 four arguments, or with arguments other than the certificate,
3412 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003413 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003414 """
3415 crl = CRL()
3416 self.assertRaises(TypeError, crl.export)
3417 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003418 with pytest.raises(TypeError):
3419 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3420 with pytest.raises(TypeError):
3421 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3422 with pytest.raises(TypeError):
3423 crl.export(self.cert, None, FILETYPE_PEM, 10)
3424 with pytest.raises(TypeError):
3425 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003426 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3427
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003428 def test_export_unknown_filetype(self):
3429 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003430 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003431 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3432 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003433 """
3434 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003435 with pytest.raises(ValueError):
3436 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003437
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003438 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003439 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003440 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003441 in a :py:obj:`ValueError` being raised.
3442 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003443 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003444 self.assertRaises(
3445 ValueError,
3446 crl.export,
3447 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3448 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003449
Rick Dean536ba022009-07-24 23:57:27 -05003450 def test_get_revoked(self):
3451 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003452 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003453 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3454 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003455 """
3456 crl = CRL()
3457
3458 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003459 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003460 revoked.set_rev_date(now)
Alex Gaynore7f51982016-09-11 11:48:14 -04003461 revoked.set_serial(b'3ab')
Rick Dean536ba022009-07-24 23:57:27 -05003462 crl.add_revoked(revoked)
Alex Gaynore7f51982016-09-11 11:48:14 -04003463 revoked.set_serial(b'100')
3464 revoked.set_reason(b'sUpErSeDEd')
Rick Dean536ba022009-07-24 23:57:27 -05003465 crl.add_revoked(revoked)
3466
3467 revs = crl.get_revoked()
3468 self.assertEqual(len(revs), 2)
3469 self.assertEqual(type(revs[0]), Revoked)
3470 self.assertEqual(type(revs[1]), Revoked)
Alex Gaynore7f51982016-09-11 11:48:14 -04003471 self.assertEqual(revs[0].get_serial(), b'03AB')
3472 self.assertEqual(revs[1].get_serial(), b'0100')
Rick Dean536ba022009-07-24 23:57:27 -05003473 self.assertEqual(revs[0].get_rev_date(), now)
3474 self.assertEqual(revs[1].get_rev_date(), now)
3475
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003476 def test_get_revoked_wrong_args(self):
3477 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003478 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3479 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003480 """
3481 crl = CRL()
3482 self.assertRaises(TypeError, crl.get_revoked, None)
3483 self.assertRaises(TypeError, crl.get_revoked, 1)
3484 self.assertRaises(TypeError, crl.get_revoked, "")
3485 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3486
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003487 def test_add_revoked_wrong_args(self):
3488 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003489 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3490 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003491 """
3492 crl = CRL()
3493 self.assertRaises(TypeError, crl.add_revoked)
3494 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3495 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3496
Rick Dean536ba022009-07-24 23:57:27 -05003497 def test_load_crl(self):
3498 """
3499 Load a known CRL and inspect its revocations. Both
3500 PEM and DER formats are loaded.
3501 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003502 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003503 revs = crl.get_revoked()
3504 self.assertEqual(len(revs), 2)
Alex Gaynore7f51982016-09-11 11:48:14 -04003505 self.assertEqual(revs[0].get_serial(), b'03AB')
Rick Dean6385faf2009-07-26 00:07:47 -05003506 self.assertEqual(revs[0].get_reason(), None)
Alex Gaynore7f51982016-09-11 11:48:14 -04003507 self.assertEqual(revs[1].get_serial(), b'0100')
3508 self.assertEqual(revs[1].get_reason(), b'Superseded')
Rick Dean536ba022009-07-24 23:57:27 -05003509
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003510 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003511 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003512 revs = crl.get_revoked()
3513 self.assertEqual(len(revs), 2)
Alex Gaynore7f51982016-09-11 11:48:14 -04003514 self.assertEqual(revs[0].get_serial(), b'03AB')
Rick Dean6385faf2009-07-26 00:07:47 -05003515 self.assertEqual(revs[0].get_reason(), None)
Alex Gaynore7f51982016-09-11 11:48:14 -04003516 self.assertEqual(revs[1].get_serial(), b'0100')
3517 self.assertEqual(revs[1].get_reason(), b'Superseded')
Rick Dean536ba022009-07-24 23:57:27 -05003518
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003519 def test_load_crl_wrong_args(self):
3520 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003521 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3522 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003523 """
3524 self.assertRaises(TypeError, load_crl)
3525 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3526 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3527
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003528 def test_load_crl_bad_filetype(self):
3529 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003530 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3531 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003532 """
3533 self.assertRaises(ValueError, load_crl, 100, crlData)
3534
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003535 def test_load_crl_bad_data(self):
3536 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003537 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3538 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003539 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003540 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003541
Dan Sully44e767a2016-06-04 18:05:27 -07003542 def test_get_issuer(self):
3543 """
3544 Load a known CRL and assert its issuer's common name is
3545 what we expect from the encoded crlData string.
3546 """
3547 crl = load_crl(FILETYPE_PEM, crlData)
3548 self.assertTrue(isinstance(crl.get_issuer(), X509Name))
3549 self.assertEqual(crl.get_issuer().CN, 'Testing Root CA')
3550
Dominic Chenf05b2122015-10-13 16:32:35 +00003551 def test_dump_crl(self):
3552 """
3553 The dumped CRL matches the original input.
3554 """
3555 crl = load_crl(FILETYPE_PEM, crlData)
3556 buf = dump_crl(FILETYPE_PEM, crl)
3557 assert buf == crlData
3558
Dan Sully44e767a2016-06-04 18:05:27 -07003559 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3560 """
3561 Create a CRL.
3562
3563 :param list[X509] certs: A list of certificates to revoke.
3564 :rtype: CRL
3565 """
3566 crl = CRL()
3567 for cert in certs:
3568 revoked = Revoked()
3569 # FIXME: This string splicing is an unfortunate implementation
3570 # detail that has been reported in
3571 # https://github.com/pyca/pyopenssl/issues/258
3572 serial = hex(cert.get_serial_number())[2:].encode('utf-8')
3573 revoked.set_serial(serial)
3574 revoked.set_reason(b'unspecified')
3575 revoked.set_rev_date(b'20140601000000Z')
3576 crl.add_revoked(revoked)
3577 crl.set_version(1)
3578 crl.set_lastUpdate(b'20140601000000Z')
3579 crl.set_nextUpdate(b'20180601000000Z')
3580 crl.sign(issuer_cert, issuer_key, digest=b'sha512')
3581 return crl
3582
3583 def test_verify_with_revoked(self):
3584 """
3585 :func:`verify_certificate` raises error when an intermediate
3586 certificate is revoked.
3587 """
3588 store = X509Store()
3589 store.add_cert(self.root_cert)
3590 store.add_cert(self.intermediate_cert)
3591 root_crl = self._make_test_crl(
3592 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3593 intermediate_crl = self._make_test_crl(
3594 self.intermediate_cert, self.intermediate_key, certs=[])
3595 store.add_crl(root_crl)
3596 store.add_crl(intermediate_crl)
3597 store.set_flags(
3598 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3599 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3600 e = self.assertRaises(
3601 X509StoreContextError, store_ctx.verify_certificate)
3602 self.assertEqual(e.args[0][2], 'certificate revoked')
3603
3604 def test_verify_with_missing_crl(self):
3605 """
3606 :func:`verify_certificate` raises error when an intermediate
3607 certificate's CRL is missing.
3608 """
3609 store = X509Store()
3610 store.add_cert(self.root_cert)
3611 store.add_cert(self.intermediate_cert)
3612 root_crl = self._make_test_crl(
3613 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3614 store.add_crl(root_crl)
3615 store.set_flags(
3616 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3617 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3618 e = self.assertRaises(
3619 X509StoreContextError, store_ctx.verify_certificate)
3620 self.assertEqual(e.args[0][2], 'unable to get certificate CRL')
3621 self.assertEqual(
3622 e.certificate.get_subject().CN, 'intermediate-service')
3623
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003624
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003625class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003626 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003627 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003628 """
3629 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3630 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003631 intermediate_server_cert = load_certificate(
3632 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003633
3634 def test_valid(self):
3635 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003636 :py:obj:`verify_certificate` returns ``None`` when called with a
3637 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003638 """
3639 store = X509Store()
3640 store.add_cert(self.root_cert)
3641 store.add_cert(self.intermediate_cert)
3642 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003643 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003644
3645 def test_reuse(self):
3646 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003647 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003648 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003649 """
3650 store = X509Store()
3651 store.add_cert(self.root_cert)
3652 store.add_cert(self.intermediate_cert)
3653 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003654 self.assertEqual(store_ctx.verify_certificate(), None)
3655 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003656
3657 def test_trusted_self_signed(self):
3658 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003659 :py:obj:`verify_certificate` returns ``None`` when called with a
3660 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003661 """
3662 store = X509Store()
3663 store.add_cert(self.root_cert)
3664 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003665 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003666
3667 def test_untrusted_self_signed(self):
3668 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003669 :py:obj:`verify_certificate` raises error when a self-signed
3670 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003671 """
3672 store = X509Store()
3673 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003674 with pytest.raises(X509StoreContextError) as exc:
3675 store_ctx.verify_certificate()
3676
3677 assert exc.value.args[0][2] == 'self signed certificate'
3678 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003679
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003680 def test_invalid_chain_no_root(self):
3681 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003682 :py:obj:`verify_certificate` raises error when a root certificate is
3683 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003684 """
3685 store = X509Store()
3686 store.add_cert(self.intermediate_cert)
3687 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003688
3689 with pytest.raises(X509StoreContextError) as exc:
3690 store_ctx.verify_certificate()
3691
3692 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3693 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003694
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003695 def test_invalid_chain_no_intermediate(self):
3696 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003697 :py:obj:`verify_certificate` raises error when an intermediate
3698 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003699 """
3700 store = X509Store()
3701 store.add_cert(self.root_cert)
3702 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003703
Alex Gaynor85b49702015-09-05 16:30:59 -04003704 with pytest.raises(X509StoreContextError) as exc:
3705 store_ctx.verify_certificate()
3706
3707 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3708 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003709
Stephen Holsapple46a09252015-02-12 14:45:43 -08003710 def test_modification_pre_verify(self):
3711 """
3712 :py:obj:`verify_certificate` can use a store context modified after
3713 instantiation.
3714 """
3715 store_bad = X509Store()
3716 store_bad.add_cert(self.intermediate_cert)
3717 store_good = X509Store()
3718 store_good.add_cert(self.root_cert)
3719 store_good.add_cert(self.intermediate_cert)
3720 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003721
3722 with pytest.raises(X509StoreContextError) as exc:
3723 store_ctx.verify_certificate()
3724
3725 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3726 assert exc.value.certificate.get_subject().CN == 'intermediate'
3727
Stephen Holsapple46a09252015-02-12 14:45:43 -08003728 store_ctx.set_store(store_good)
3729 self.assertEqual(store_ctx.verify_certificate(), None)
3730
3731
James Yonan7c2e5d32010-02-27 05:45:50 -07003732class SignVerifyTests(TestCase):
3733 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003734 Tests for :py:obj:`OpenSSL.crypto.sign` and
3735 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003736 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003737
James Yonan7c2e5d32010-02-27 05:45:50 -07003738 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003739 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003740 :py:obj:`sign` generates a cryptographic signature which
3741 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003742 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003743 content = (
3744 b"It was a bright cold day in April, and the clocks were striking "
3745 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3746 b"effort to escape the vile wind, slipped quickly through the "
3747 b"glass doors of Victory Mansions, though not quickly enough to "
3748 b"prevent a swirl of gritty dust from entering along with him.")
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003749
3750 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003751 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003752 # verify the content with this cert
3753 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3754 # certificate unrelated to priv_key, used to trigger an error
3755 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003756
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003757 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003758 sig = sign(priv_key, content, digest)
3759
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003760 # Verify the signature of content, will throw an exception if
3761 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003762 verify(good_cert, sig, content, digest)
3763
3764 # This should fail because the certificate doesn't match the
3765 # private key that was used to sign the content.
3766 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3767
3768 # This should fail because we've "tainted" the content after
3769 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003770 self.assertRaises(
3771 Error, verify,
Alex Gaynore7f51982016-09-11 11:48:14 -04003772 good_cert, sig, content + b"tainted", digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003773
3774 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003775 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003776 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003777 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003778 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003779
Abraham Martinc5484ba2015-03-25 15:33:05 +00003780 def test_sign_verify_with_text(self):
3781 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003782 :py:obj:`sign` generates a cryptographic signature which
3783 :py:obj:`verify` can check. Deprecation warnings raised because using
3784 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003785 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003786 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003787 b"It was a bright cold day in April, and the clocks were striking "
3788 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3789 b"effort to escape the vile wind, slipped quickly through the "
3790 b"glass doors of Victory Mansions, though not quickly enough to "
3791 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003792 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003793
3794 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3795 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3796 for digest in ['md5', 'sha1']:
3797 with catch_warnings(record=True) as w:
3798 simplefilter("always")
3799 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003800
3801 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003802 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003803 WARNING_TYPE_EXPECTED
3804 ),
3805 str(w[-1].message)
3806 )
3807 self.assertIs(w[-1].category, DeprecationWarning)
3808
Abraham Martinc5484ba2015-03-25 15:33:05 +00003809 with catch_warnings(record=True) as w:
3810 simplefilter("always")
3811 verify(cert, sig, 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)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003820
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003821 def test_sign_nulls(self):
3822 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003823 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003824 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003825 content = b"Watch out! \0 Did you see it?"
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003826 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3827 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3828 sig = sign(priv_key, content, "sha1")
3829 verify(good_cert, sig, content, "sha1")
3830
Colleen Murphye09399b2016-03-01 17:40:49 -08003831 def test_sign_with_large_key(self):
3832 """
3833 :py:obj:`sign` produces a signature for a string when using a long key.
3834 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003835 content = (
3836 b"It was a bright cold day in April, and the clocks were striking "
3837 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3838 b"effort to escape the vile wind, slipped quickly through the "
3839 b"glass doors of Victory Mansions, though not quickly enough to "
3840 b"prevent a swirl of gritty dust from entering along with him.")
Colleen Murphye09399b2016-03-01 17:40:49 -08003841
3842 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3843 sign(priv_key, content, "sha1")
3844
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003845
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003846class EllipticCurveTests(TestCase):
3847 """
3848 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3849 :py:obj:`get_elliptic_curves`.
3850 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003851
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003852 def test_set(self):
3853 """
3854 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3855 """
3856 self.assertIsInstance(get_elliptic_curves(), set)
3857
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003858 def test_some_curves(self):
3859 """
3860 If :py:mod:`cryptography` has elliptic curve support then the set
3861 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3862 it.
3863
3864 There could be an OpenSSL that violates this assumption. If so, this
3865 test will fail and we'll find out.
3866 """
3867 curves = get_elliptic_curves()
3868 if lib.Cryptography_HAS_EC:
3869 self.assertTrue(curves)
3870 else:
3871 self.assertFalse(curves)
3872
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003873 def test_a_curve(self):
3874 """
3875 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3876 supported curve.
3877 """
3878 curves = get_elliptic_curves()
3879 if curves:
3880 curve = next(iter(curves))
3881 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3882 else:
Alex Gaynore7f51982016-09-11 11:48:14 -04003883 self.assertRaises(ValueError, get_elliptic_curve, u"prime256v1")
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003884
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003885 def test_not_a_curve(self):
3886 """
3887 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3888 with a name which does not identify a supported curve.
3889 """
3890 self.assertRaises(
Alex Gaynore7f51982016-09-11 11:48:14 -04003891 ValueError, get_elliptic_curve, u"this curve was just invented")
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003892
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003893 def test_repr(self):
3894 """
3895 The string representation of a curve object includes simply states the
3896 object is a curve and what its name is.
3897 """
3898 curves = get_elliptic_curves()
3899 if curves:
3900 curve = next(iter(curves))
3901 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3902
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003903 def test_to_EC_KEY(self):
3904 """
3905 The curve object can export a version of itself as an EC_KEY* via the
3906 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3907 """
3908 curves = get_elliptic_curves()
3909 if curves:
3910 curve = next(iter(curves))
3911 # It's not easy to assert anything about this object. However, see
3912 # leakcheck/crypto.py for a test that demonstrates it at least does
3913 # not leak memory.
3914 curve._to_EC_KEY()
3915
3916
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003917class EllipticCurveFactory(object):
3918 """
3919 A helper to get the names of two curves.
3920 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003921
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003922 def __init__(self):
3923 curves = iter(get_elliptic_curves())
3924 try:
3925 self.curve_name = next(curves).name
3926 self.another_curve_name = next(curves).name
3927 except StopIteration:
3928 self.curve_name = self.another_curve_name = None
3929
3930
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003931class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3932 """
3933 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3934 """
3935 curve_factory = EllipticCurveFactory()
3936
3937 if curve_factory.curve_name is None:
3938 skip = "There are no curves available there can be no curve objects."
3939
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003940 def anInstance(self):
3941 """
3942 Get the curve object for an arbitrary curve supported by the system.
3943 """
3944 return get_elliptic_curve(self.curve_factory.curve_name)
3945
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003946 def anotherInstance(self):
3947 """
3948 Get the curve object for an arbitrary curve supported by the system -
3949 but not the one returned by C{anInstance}.
3950 """
3951 return get_elliptic_curve(self.curve_factory.another_curve_name)
3952
3953
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003954class EllipticCurveHashTests(TestCase):
3955 """
3956 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3957 as an item in a :py:type:`dict` or :py:type:`set`).
3958 """
3959 curve_factory = EllipticCurveFactory()
3960
3961 if curve_factory.curve_name is None:
3962 skip = "There are no curves available there can be no curve objects."
3963
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003964 def test_contains(self):
3965 """
3966 The ``in`` operator reports that a :py:type:`set` containing a curve
3967 does contain that curve.
3968 """
3969 curve = get_elliptic_curve(self.curve_factory.curve_name)
3970 curves = set([curve])
3971 self.assertIn(curve, curves)
3972
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003973 def test_does_not_contain(self):
3974 """
3975 The ``in`` operator reports that a :py:type:`set` not containing a
3976 curve does not contain that curve.
3977 """
3978 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003979 curves = set([
3980 get_elliptic_curve(self.curve_factory.another_curve_name)
3981 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003982 self.assertNotIn(curve, curves)