blob: 6b55702562dbb99c5648a808c1a6aaafc9831b03 [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)
Alex Chan63ef9bc2016-12-19 12:02:06 +000046from OpenSSL._util import native
Hynek Schlawackf0e66852015-10-16 20:18:38 +020047
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 """
Alex Chandeec9342016-12-19 22:00:38 +00003118 Tests for `OpenSSL.crypto.Revoked`.
Paul Kehrer2c605ba2016-03-11 11:17:26 -04003119 """
3120 def test_ignores_unsupported_revoked_cert_extension_get_reason(self):
3121 """
3122 The get_reason method on the Revoked class checks to see if the
3123 extension is NID_crl_reason and should skip it otherwise. This test
3124 loads a CRL with extensions it should ignore.
3125 """
3126 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3127 revoked = crl.get_revoked()
3128 reason = revoked[1].get_reason()
3129 assert reason == b'Unspecified'
3130
3131 def test_ignores_unsupported_revoked_cert_extension_set_new_reason(self):
3132 crl = load_crl(FILETYPE_PEM, crlDataUnsupportedExtension)
3133 revoked = crl.get_revoked()
3134 revoked[1].set_reason(None)
3135 reason = revoked[1].get_reason()
3136 assert reason is None
3137
Rick Dean536ba022009-07-24 23:57:27 -05003138 def test_construction(self):
3139 """
Alex Chandeec9342016-12-19 22:00:38 +00003140 Confirm we can create `OpenSSL.crypto.Revoked`. Check that it is
3141 empty.
Rick Dean536ba022009-07-24 23:57:27 -05003142 """
3143 revoked = Revoked()
Alex Chandeec9342016-12-19 22:00:38 +00003144 assert isinstance(revoked, Revoked)
3145 assert type(revoked) == Revoked
3146 assert revoked.get_serial() == b'00'
3147 assert revoked.get_rev_date() is None
3148 assert revoked.get_reason() is None
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003149
Rick Dean536ba022009-07-24 23:57:27 -05003150 def test_serial(self):
3151 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003152 Confirm we can set and get serial numbers from
Alex Chandeec9342016-12-19 22:00:38 +00003153 `OpenSSL.crypto.Revoked`. Confirm errors are handled with grace.
Rick Dean536ba022009-07-24 23:57:27 -05003154 """
3155 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003156 ret = revoked.set_serial(b'10b')
Alex Chandeec9342016-12-19 22:00:38 +00003157 assert ret is None
Rick Dean536ba022009-07-24 23:57:27 -05003158 ser = revoked.get_serial()
Alex Chandeec9342016-12-19 22:00:38 +00003159 assert ser == b'010B'
Rick Dean536ba022009-07-24 23:57:27 -05003160
Alex Gaynore7f51982016-09-11 11:48:14 -04003161 revoked.set_serial(b'31ppp') # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05003162 ser = revoked.get_serial()
Alex Chandeec9342016-12-19 22:00:38 +00003163 assert ser == b'31'
Rick Dean536ba022009-07-24 23:57:27 -05003164
Alex Chandeec9342016-12-19 22:00:38 +00003165 with pytest.raises(ValueError):
3166 revoked.set_serial(b'pqrst')
3167 with pytest.raises(TypeError):
3168 revoked.set_serial(100)
Rick Dean536ba022009-07-24 23:57:27 -05003169
Rick Dean536ba022009-07-24 23:57:27 -05003170 def test_date(self):
3171 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003172 Confirm we can set and get revocation dates from
Alex Chandeec9342016-12-19 22:00:38 +00003173 `OpenSSL.crypto.Revoked`. Confirm errors are handled with grace.
Rick Dean536ba022009-07-24 23:57:27 -05003174 """
3175 revoked = Revoked()
3176 date = revoked.get_rev_date()
Alex Chandeec9342016-12-19 22:00:38 +00003177 assert date is None
Rick Dean536ba022009-07-24 23:57:27 -05003178
Alex Gaynore7f51982016-09-11 11:48:14 -04003179 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003180 ret = revoked.set_rev_date(now)
Alex Chandeec9342016-12-19 22:00:38 +00003181 assert ret is None
Rick Dean536ba022009-07-24 23:57:27 -05003182 date = revoked.get_rev_date()
Alex Chandeec9342016-12-19 22:00:38 +00003183 assert date == now
Rick Dean536ba022009-07-24 23:57:27 -05003184
Rick Dean6385faf2009-07-26 00:07:47 -05003185 def test_reason(self):
3186 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003187 Confirm we can set and get revocation reasons from
Alex Chandeec9342016-12-19 22:00:38 +00003188 `OpenSSL.crypto.Revoked`. The "get" need to work as "set".
3189 Likewise, each reason of all_reasons() must work.
Rick Dean6385faf2009-07-26 00:07:47 -05003190 """
3191 revoked = Revoked()
3192 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003193 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003194 ret = revoked.set_reason(r)
Alex Chandeec9342016-12-19 22:00:38 +00003195 assert ret is None
Rick Dean6385faf2009-07-26 00:07:47 -05003196 reason = revoked.get_reason()
Alex Chandeec9342016-12-19 22:00:38 +00003197 assert (
3198 reason.lower().replace(b' ', b'') ==
Alex Gaynore7f51982016-09-11 11:48:14 -04003199 r.lower().replace(b' ', b''))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003200 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003201
3202 revoked.set_reason(None)
Alex Chandeec9342016-12-19 22:00:38 +00003203 assert revoked.get_reason() is None
Rick Dean6385faf2009-07-26 00:07:47 -05003204
Alex Chandeec9342016-12-19 22:00:38 +00003205 def test_set_reason_invalid_reason(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003206 """
Alex Chandeec9342016-12-19 22:00:38 +00003207 Calling `OpenSSL.crypto.Revoked.set_reason` with an argument which
3208 isn't a valid reason results in `ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003209 """
3210 revoked = Revoked()
Alex Chandeec9342016-12-19 22:00:38 +00003211 with pytest.raises(ValueError):
3212 revoked.set_reason(b'blue')
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003213
3214
Alex Chan7be83a52017-01-24 15:19:29 +00003215class TestCRL(object):
Rick Dean536ba022009-07-24 23:57:27 -05003216 """
Alex Chan7be83a52017-01-24 15:19:29 +00003217 Tests for `OpenSSL.crypto.CRL`.
Rick Dean536ba022009-07-24 23:57:27 -05003218 """
3219 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3220 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3221
Dan Sully44e767a2016-06-04 18:05:27 -07003222 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3223 root_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3224 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
3225 intermediate_key = load_privatekey(FILETYPE_PEM, intermediate_key_pem)
3226 intermediate_server_cert = load_certificate(
3227 FILETYPE_PEM, intermediate_server_cert_pem)
3228 intermediate_server_key = load_privatekey(
3229 FILETYPE_PEM, intermediate_server_key_pem)
3230
Rick Dean536ba022009-07-24 23:57:27 -05003231 def test_construction(self):
3232 """
Alex Chan7be83a52017-01-24 15:19:29 +00003233 Confirm we can create `OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003234 that it is empty
3235 """
3236 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003237 assert isinstance(crl, CRL)
3238 assert crl.get_revoked() is None
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003239
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003240 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003241 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003242 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003243 """
3244 crl = CRL()
3245 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003246 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003247 revoked.set_rev_date(now)
Alex Gaynore7f51982016-09-11 11:48:14 -04003248 revoked.set_serial(b'3ab')
3249 revoked.set_reason(b'sUpErSeDEd')
Rick Dean536ba022009-07-24 23:57:27 -05003250 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003251 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003252
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003253 def test_export_pem(self):
3254 """
3255 If not passed a format, ``CRL.export`` returns a "PEM" format string
3256 representing a serial number, a revoked reason, and certificate issuer
3257 information.
3258 """
3259 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003260 # PEM format
3261 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003262 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003263
3264 # These magic values are based on the way the CRL above was constructed
3265 # and with what certificate it was exported.
Alex Gaynore7f51982016-09-11 11:48:14 -04003266 text.index(b'Serial Number: 03AB')
3267 text.index(b'Superseded')
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003268 text.index(
Alex Gaynore7f51982016-09-11 11:48:14 -04003269 b'Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA'
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003270 )
3271
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003272 def test_export_der(self):
3273 """
3274 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3275 "DER" format string representing a serial number, a revoked reason, and
3276 certificate issuer information.
3277 """
3278 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003279
3280 # DER format
3281 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003282 text = _runopenssl(
3283 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3284 )
Alex Gaynore7f51982016-09-11 11:48:14 -04003285 text.index(b'Serial Number: 03AB')
3286 text.index(b'Superseded')
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003287 text.index(
Alex Gaynore7f51982016-09-11 11:48:14 -04003288 b'Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA'
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003289 )
3290
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003291 def test_export_text(self):
3292 """
3293 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3294 text format string like the one produced by the openssl command line
3295 tool.
3296 """
3297 crl = self._get_crl()
3298
3299 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3300 text = _runopenssl(
3301 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3302 )
Rick Dean536ba022009-07-24 23:57:27 -05003303
3304 # text format
3305 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
Alex Chan7be83a52017-01-24 15:19:29 +00003306 assert text == dumped_text
Rick Dean536ba022009-07-24 23:57:27 -05003307
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003308 def test_export_custom_digest(self):
3309 """
3310 If passed the name of a digest function, ``CRL.export`` uses a
3311 signature algorithm based on that digest function.
3312 """
3313 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003314 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003315 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynore7f51982016-09-11 11:48:14 -04003316 text.index(b'Signature Algorithm: sha1')
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003317
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003318 def test_export_md5_digest(self):
3319 """
3320 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3321 not emit a deprecation warning.
3322 """
3323 crl = self._get_crl()
Alex Chan7be83a52017-01-24 15:19:29 +00003324 with pytest.warns(None) as catcher:
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003325 simplefilter("always")
Alex Chan7be83a52017-01-24 15:19:29 +00003326 assert 0 == len(catcher)
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003327 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3328 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynore7f51982016-09-11 11:48:14 -04003329 text.index(b'Signature Algorithm: md5')
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003330
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003331 def test_export_default_digest(self):
3332 """
3333 If not passed the name of a digest function, ``CRL.export`` uses a
3334 signature algorithm based on MD5 and emits a deprecation warning.
3335 """
3336 crl = self._get_crl()
Alex Chan7be83a52017-01-24 15:19:29 +00003337 with pytest.warns(None) as catcher:
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003338 simplefilter("always")
3339 dumped_crl = crl.export(self.cert, self.pkey)
Alex Chan7be83a52017-01-24 15:19:29 +00003340 assert (
3341 "The default message digest (md5) is deprecated. "
3342 "Pass the name of a message digest explicitly." ==
3343 str(catcher[0].message)
3344 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003345 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Alex Gaynore7f51982016-09-11 11:48:14 -04003346 text.index(b'Signature Algorithm: md5')
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003347
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003348 def test_export_invalid(self):
3349 """
Alex Chan7be83a52017-01-24 15:19:29 +00003350 If `CRL.export` is used with an uninitialized `X509` instance,
3351 `OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003352 """
3353 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003354 with pytest.raises(Error):
3355 crl.export(X509(), PKey())
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003356
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003357 def test_add_revoked_keyword(self):
3358 """
Alex Chan7be83a52017-01-24 15:19:29 +00003359 `OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003360 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003361 """
3362 crl = CRL()
3363 revoked = Revoked()
Paul Kehrerb11bffc2016-03-10 18:30:29 -04003364 revoked.set_serial(b"01")
Paul Kehrer2fe23b02016-03-09 22:02:15 -04003365 revoked.set_rev_date(b"20160310020145Z")
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003366 crl.add_revoked(revoked=revoked)
Alex Chan7be83a52017-01-24 15:19:29 +00003367 assert isinstance(crl.get_revoked()[0], Revoked)
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003368
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003369 def test_export_wrong_args(self):
3370 """
Alex Chan7be83a52017-01-24 15:19:29 +00003371 Calling `OpenSSL.CRL.export` with arguments other than the certificate,
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003372 private key, integer file type, and integer number of days it
Alex Chan7be83a52017-01-24 15:19:29 +00003373 expects, results in a `TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003374 """
3375 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003376 with pytest.raises(TypeError):
3377 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3378 with pytest.raises(TypeError):
3379 crl.export(self.cert, None, FILETYPE_PEM, 10)
3380 with pytest.raises(TypeError):
3381 crl.export(self.cert, self.pkey, None, 10)
Alex Chan7be83a52017-01-24 15:19:29 +00003382 with pytest.raises(TypeError):
3383 crl.export(self.cert, FILETYPE_PEM, None)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003384
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003385 def test_export_unknown_filetype(self):
3386 """
Alex Chan7be83a52017-01-24 15:19:29 +00003387 Calling `OpenSSL.CRL.export` with a file type other than
3388 `FILETYPE_PEM`, `FILETYPE_ASN1`, or
3389 `FILETYPE_TEXT` results in a `ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003390 """
3391 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003392 with pytest.raises(ValueError):
3393 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003394
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003395 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003396 """
Alex Chan7be83a52017-01-24 15:19:29 +00003397 Calling `OpenSSL.CRL.export` with an unsupported digest results
3398 in a `ValueError` being raised.
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003399 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003400 crl = CRL()
Alex Chan7be83a52017-01-24 15:19:29 +00003401 with pytest.raises(ValueError):
3402 crl.export(
3403 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest")
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003404
Rick Dean536ba022009-07-24 23:57:27 -05003405 def test_get_revoked(self):
3406 """
Alex Chan7be83a52017-01-24 15:19:29 +00003407 Use python to create a simple CRL with two revocations. Get back the
3408 `Revoked` using `OpenSSL.CRL.get_revoked` and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003409 """
3410 crl = CRL()
3411
3412 revoked = Revoked()
Alex Gaynore7f51982016-09-11 11:48:14 -04003413 now = datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")
Rick Dean536ba022009-07-24 23:57:27 -05003414 revoked.set_rev_date(now)
Alex Gaynore7f51982016-09-11 11:48:14 -04003415 revoked.set_serial(b'3ab')
Rick Dean536ba022009-07-24 23:57:27 -05003416 crl.add_revoked(revoked)
Alex Gaynore7f51982016-09-11 11:48:14 -04003417 revoked.set_serial(b'100')
3418 revoked.set_reason(b'sUpErSeDEd')
Rick Dean536ba022009-07-24 23:57:27 -05003419 crl.add_revoked(revoked)
3420
3421 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003422 assert len(revs) == 2
3423 assert type(revs[0]) == Revoked
3424 assert type(revs[1]) == Revoked
3425 assert revs[0].get_serial() == b'03AB'
3426 assert revs[1].get_serial() == b'0100'
3427 assert revs[0].get_rev_date() == now
3428 assert revs[1].get_rev_date() == now
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003429
Rick Dean536ba022009-07-24 23:57:27 -05003430 def test_load_crl(self):
3431 """
Alex Chan7be83a52017-01-24 15:19:29 +00003432 Load a known CRL and inspect its revocations. Both EM and DER formats
3433 are loaded.
Rick Dean536ba022009-07-24 23:57:27 -05003434 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003435 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003436 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003437 assert len(revs) == 2
3438 assert revs[0].get_serial() == b'03AB'
3439 assert revs[0].get_reason() is None
3440 assert revs[1].get_serial() == b'0100'
3441 assert revs[1].get_reason() == b'Superseded'
Rick Dean536ba022009-07-24 23:57:27 -05003442
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003443 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003444 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003445 revs = crl.get_revoked()
Alex Chan7be83a52017-01-24 15:19:29 +00003446 assert len(revs) == 2
3447 assert revs[0].get_serial() == b'03AB'
3448 assert revs[0].get_reason() is None
3449 assert revs[1].get_serial() == b'0100'
3450 assert revs[1].get_reason() == b'Superseded'
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003451
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003452 def test_load_crl_bad_filetype(self):
3453 """
Alex Chan7be83a52017-01-24 15:19:29 +00003454 Calling `OpenSSL.crypto.load_crl` with an unknown file type raises a
3455 `ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003456 """
Alex Chan7be83a52017-01-24 15:19:29 +00003457 with pytest.raises(ValueError):
3458 load_crl(100, crlData)
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003459
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003460 def test_load_crl_bad_data(self):
3461 """
Alex Chan7be83a52017-01-24 15:19:29 +00003462 Calling `OpenSSL.crypto.load_crl` with file data which can't be loaded
3463 raises a `OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003464 """
Alex Chan7be83a52017-01-24 15:19:29 +00003465 with pytest.raises(Error):
3466 load_crl(FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003467
Dan Sully44e767a2016-06-04 18:05:27 -07003468 def test_get_issuer(self):
3469 """
Alex Chan7be83a52017-01-24 15:19:29 +00003470 Load a known CRL and assert its issuer's common name is what we expect
3471 from the encoded crlData string.
Dan Sully44e767a2016-06-04 18:05:27 -07003472 """
3473 crl = load_crl(FILETYPE_PEM, crlData)
Alex Chan7be83a52017-01-24 15:19:29 +00003474 assert isinstance(crl.get_issuer(), X509Name)
3475 assert crl.get_issuer().CN == 'Testing Root CA'
Dan Sully44e767a2016-06-04 18:05:27 -07003476
Dominic Chenf05b2122015-10-13 16:32:35 +00003477 def test_dump_crl(self):
3478 """
3479 The dumped CRL matches the original input.
3480 """
3481 crl = load_crl(FILETYPE_PEM, crlData)
3482 buf = dump_crl(FILETYPE_PEM, crl)
3483 assert buf == crlData
3484
Dan Sully44e767a2016-06-04 18:05:27 -07003485 def _make_test_crl(self, issuer_cert, issuer_key, certs=()):
3486 """
3487 Create a CRL.
3488
3489 :param list[X509] certs: A list of certificates to revoke.
3490 :rtype: CRL
3491 """
3492 crl = CRL()
3493 for cert in certs:
3494 revoked = Revoked()
3495 # FIXME: This string splicing is an unfortunate implementation
3496 # detail that has been reported in
3497 # https://github.com/pyca/pyopenssl/issues/258
3498 serial = hex(cert.get_serial_number())[2:].encode('utf-8')
3499 revoked.set_serial(serial)
3500 revoked.set_reason(b'unspecified')
3501 revoked.set_rev_date(b'20140601000000Z')
3502 crl.add_revoked(revoked)
3503 crl.set_version(1)
3504 crl.set_lastUpdate(b'20140601000000Z')
3505 crl.set_nextUpdate(b'20180601000000Z')
3506 crl.sign(issuer_cert, issuer_key, digest=b'sha512')
3507 return crl
3508
3509 def test_verify_with_revoked(self):
3510 """
Alex Chan7be83a52017-01-24 15:19:29 +00003511 `verify_certificate` raises error when an intermediate certificate is
3512 revoked.
Dan Sully44e767a2016-06-04 18:05:27 -07003513 """
3514 store = X509Store()
3515 store.add_cert(self.root_cert)
3516 store.add_cert(self.intermediate_cert)
3517 root_crl = self._make_test_crl(
3518 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3519 intermediate_crl = self._make_test_crl(
3520 self.intermediate_cert, self.intermediate_key, certs=[])
3521 store.add_crl(root_crl)
3522 store.add_crl(intermediate_crl)
3523 store.set_flags(
3524 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3525 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003526 with pytest.raises(X509StoreContextError) as err:
3527 store_ctx.verify_certificate()
3528 assert err.value.args[0][2] == 'certificate revoked'
Dan Sully44e767a2016-06-04 18:05:27 -07003529
3530 def test_verify_with_missing_crl(self):
3531 """
Alex Chan7be83a52017-01-24 15:19:29 +00003532 `verify_certificate` raises error when an intermediate certificate's
3533 CRL is missing.
Dan Sully44e767a2016-06-04 18:05:27 -07003534 """
3535 store = X509Store()
3536 store.add_cert(self.root_cert)
3537 store.add_cert(self.intermediate_cert)
3538 root_crl = self._make_test_crl(
3539 self.root_cert, self.root_key, certs=[self.intermediate_cert])
3540 store.add_crl(root_crl)
3541 store.set_flags(
3542 X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
3543 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003544 with pytest.raises(X509StoreContextError) as err:
3545 store_ctx.verify_certificate()
3546 assert err.value.args[0][2] == 'unable to get certificate CRL'
3547 assert err.value.certificate.get_subject().CN == 'intermediate-service'
Dan Sully44e767a2016-06-04 18:05:27 -07003548
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003549
Alex Chan7be83a52017-01-24 15:19:29 +00003550class TestX509StoreContext(object):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003551 """
Alex Chan7be83a52017-01-24 15:19:29 +00003552 Tests for `OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003553 """
3554 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3555 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003556 intermediate_server_cert = load_certificate(
3557 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003558
3559 def test_valid(self):
3560 """
Alex Chan7be83a52017-01-24 15:19:29 +00003561 `verify_certificate` returns ``None`` when called with a certificate
3562 and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003563 """
3564 store = X509Store()
3565 store.add_cert(self.root_cert)
3566 store.add_cert(self.intermediate_cert)
3567 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003568 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003569
3570 def test_reuse(self):
3571 """
Alex Chan7be83a52017-01-24 15:19:29 +00003572 `verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003573 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003574 """
3575 store = X509Store()
3576 store.add_cert(self.root_cert)
3577 store.add_cert(self.intermediate_cert)
3578 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003579 assert store_ctx.verify_certificate() is None
3580 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003581
3582 def test_trusted_self_signed(self):
3583 """
Alex Chan7be83a52017-01-24 15:19:29 +00003584 `verify_certificate` returns ``None`` when called with a self-signed
3585 certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003586 """
3587 store = X509Store()
3588 store.add_cert(self.root_cert)
3589 store_ctx = X509StoreContext(store, self.root_cert)
Alex Chan7be83a52017-01-24 15:19:29 +00003590 assert store_ctx.verify_certificate() is None
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003591
3592 def test_untrusted_self_signed(self):
3593 """
Alex Chan7be83a52017-01-24 15:19:29 +00003594 `verify_certificate` raises error when a self-signed certificate is
3595 verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003596 """
3597 store = X509Store()
3598 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003599 with pytest.raises(X509StoreContextError) as exc:
3600 store_ctx.verify_certificate()
3601
3602 assert exc.value.args[0][2] == 'self signed certificate'
3603 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003604
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003605 def test_invalid_chain_no_root(self):
3606 """
Alex Chan7be83a52017-01-24 15:19:29 +00003607 `verify_certificate` raises error when a root certificate is missing
3608 from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003609 """
3610 store = X509Store()
3611 store.add_cert(self.intermediate_cert)
3612 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003613
3614 with pytest.raises(X509StoreContextError) as exc:
3615 store_ctx.verify_certificate()
3616
3617 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3618 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003619
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003620 def test_invalid_chain_no_intermediate(self):
3621 """
Alex Chan7be83a52017-01-24 15:19:29 +00003622 `verify_certificate` raises error when an intermediate certificate is
3623 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003624 """
3625 store = X509Store()
3626 store.add_cert(self.root_cert)
3627 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003628
Alex Gaynor85b49702015-09-05 16:30:59 -04003629 with pytest.raises(X509StoreContextError) as exc:
3630 store_ctx.verify_certificate()
3631
3632 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3633 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003634
Stephen Holsapple46a09252015-02-12 14:45:43 -08003635 def test_modification_pre_verify(self):
3636 """
Alex Chan7be83a52017-01-24 15:19:29 +00003637 `verify_certificate` can use a store context modified after
Stephen Holsapple46a09252015-02-12 14:45:43 -08003638 instantiation.
3639 """
3640 store_bad = X509Store()
3641 store_bad.add_cert(self.intermediate_cert)
3642 store_good = X509Store()
3643 store_good.add_cert(self.root_cert)
3644 store_good.add_cert(self.intermediate_cert)
3645 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003646
3647 with pytest.raises(X509StoreContextError) as exc:
3648 store_ctx.verify_certificate()
3649
3650 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3651 assert exc.value.certificate.get_subject().CN == 'intermediate'
3652
Stephen Holsapple46a09252015-02-12 14:45:43 -08003653 store_ctx.set_store(store_good)
Alex Chan7be83a52017-01-24 15:19:29 +00003654 assert store_ctx.verify_certificate() is None
Stephen Holsapple46a09252015-02-12 14:45:43 -08003655
Thomas Sileoe15e60a2016-11-22 18:13:30 +01003656 def test_verify_with_time(self):
3657 """
3658 `verify_certificate` raises error when the verification time is
3659 set at notAfter.
3660 """
3661 store = X509Store()
3662 store.add_cert(self.root_cert)
3663 store.add_cert(self.intermediate_cert)
3664
3665 expire_time = self.intermediate_server_cert.get_notAfter()
3666 expire_datetime = datetime.strptime(
3667 expire_time.decode('utf-8'), '%Y%m%d%H%M%SZ'
3668 )
3669 store.set_time(expire_datetime)
3670
3671 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
3672 with pytest.raises(X509StoreContextError) as exc:
3673 store_ctx.verify_certificate()
3674
3675 assert exc.value.args[0][2] == 'certificate has expired'
3676
Stephen Holsapple46a09252015-02-12 14:45:43 -08003677
Alex Chan7be83a52017-01-24 15:19:29 +00003678class TestSignVerify(object):
James Yonan7c2e5d32010-02-27 05:45:50 -07003679 """
Alex Chan7be83a52017-01-24 15:19:29 +00003680 Tests for `OpenSSL.crypto.sign` and `OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003681 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003682
James Yonan7c2e5d32010-02-27 05:45:50 -07003683 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003684 """
Alex Chan7be83a52017-01-24 15:19:29 +00003685 `sign` generates a cryptographic signature which `verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003686 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003687 content = (
3688 b"It was a bright cold day in April, and the clocks were striking "
3689 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3690 b"effort to escape the vile wind, slipped quickly through the "
3691 b"glass doors of Victory Mansions, though not quickly enough to "
3692 b"prevent a swirl of gritty dust from entering along with him.")
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003693
3694 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003695 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003696 # verify the content with this cert
3697 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3698 # certificate unrelated to priv_key, used to trigger an error
3699 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003700
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003701 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003702 sig = sign(priv_key, content, digest)
3703
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003704 # Verify the signature of content, will throw an exception if
3705 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003706 verify(good_cert, sig, content, digest)
3707
3708 # This should fail because the certificate doesn't match the
3709 # private key that was used to sign the content.
Alex Chan7be83a52017-01-24 15:19:29 +00003710 with pytest.raises(Error):
3711 verify(bad_cert, sig, content, digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003712
3713 # This should fail because we've "tainted" the content after
3714 # signing it.
Alex Chan7be83a52017-01-24 15:19:29 +00003715 with pytest.raises(Error):
3716 verify(good_cert, sig, content + b"tainted", digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003717
3718 # test that unknown digest types fail
Alex Chan7be83a52017-01-24 15:19:29 +00003719 with pytest.raises(ValueError):
3720 sign(priv_key, content, "strange-digest")
3721 with pytest.raises(ValueError):
3722 verify(good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003723
Abraham Martinc5484ba2015-03-25 15:33:05 +00003724 def test_sign_verify_with_text(self):
3725 """
Alex Chan7be83a52017-01-24 15:19:29 +00003726 `sign` generates a cryptographic signature which
3727 `verify` can check. Deprecation warnings raised because using
Alex Gaynor791212d2015-09-05 15:46:08 -04003728 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003729 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003730 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003731 b"It was a bright cold day in April, and the clocks were striking "
3732 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3733 b"effort to escape the vile wind, slipped quickly through the "
3734 b"glass doors of Victory Mansions, though not quickly enough to "
3735 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003736 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003737
3738 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3739 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3740 for digest in ['md5', 'sha1']:
Alex Chan7be83a52017-01-24 15:19:29 +00003741 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00003742 simplefilter("always")
3743 sig = sign(priv_key, content, digest)
Alex Chan7be83a52017-01-24 15:19:29 +00003744 assert (
3745 "{0} for data is no longer accepted, use bytes".format(
3746 WARNING_TYPE_EXPECTED
3747 ) == str(w[-1].message))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003748
Alex Chan7be83a52017-01-24 15:19:29 +00003749 with pytest.warns(DeprecationWarning) as w:
Abraham Martinc5484ba2015-03-25 15:33:05 +00003750 simplefilter("always")
3751 verify(cert, sig, content, digest)
Alex Chan7be83a52017-01-24 15:19:29 +00003752 assert (
3753 "{0} for data is no longer accepted, use bytes".format(
3754 WARNING_TYPE_EXPECTED
3755 ) == str(w[-1].message))
Abraham Martinc5484ba2015-03-25 15:33:05 +00003756
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003757 def test_sign_nulls(self):
3758 """
Alex Chan7be83a52017-01-24 15:19:29 +00003759 `sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003760 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003761 content = b"Watch out! \0 Did you see it?"
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003762 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3763 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3764 sig = sign(priv_key, content, "sha1")
3765 verify(good_cert, sig, content, "sha1")
3766
Colleen Murphye09399b2016-03-01 17:40:49 -08003767 def test_sign_with_large_key(self):
3768 """
Alex Chan7be83a52017-01-24 15:19:29 +00003769 `sign` produces a signature for a string when using a long key.
Colleen Murphye09399b2016-03-01 17:40:49 -08003770 """
Alex Gaynore7f51982016-09-11 11:48:14 -04003771 content = (
3772 b"It was a bright cold day in April, and the clocks were striking "
3773 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3774 b"effort to escape the vile wind, slipped quickly through the "
3775 b"glass doors of Victory Mansions, though not quickly enough to "
3776 b"prevent a swirl of gritty dust from entering along with him.")
Colleen Murphye09399b2016-03-01 17:40:49 -08003777
3778 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3779 sign(priv_key, content, "sha1")
3780
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003781
Alex Chan63ef9bc2016-12-19 12:02:06 +00003782class TestEllipticCurve(object):
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003783 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003784 Tests for `_EllipticCurve`, `get_elliptic_curve`, and
3785 `get_elliptic_curves`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003786 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003787
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003788 def test_set(self):
3789 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003790 `get_elliptic_curves` returns a `set`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003791 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003792 assert isinstance(get_elliptic_curves(), set)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003793
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003794 def test_a_curve(self):
3795 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003796 `get_elliptic_curve` can be used to retrieve a particular supported
3797 curve.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003798 """
3799 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00003800 curve = next(iter(curves))
3801 assert curve.name == get_elliptic_curve(curve.name).name
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003802
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003803 def test_not_a_curve(self):
3804 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003805 `get_elliptic_curve` raises `ValueError` if called with a name which
3806 does not identify a supported curve.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003807 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003808 with pytest.raises(ValueError):
3809 get_elliptic_curve(u"this curve was just invented")
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003810
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003811 def test_repr(self):
3812 """
3813 The string representation of a curve object includes simply states the
3814 object is a curve and what its name is.
3815 """
3816 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00003817 curve = next(iter(curves))
3818 assert "<Curve %r>" % (curve.name,) == repr(curve)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003819
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003820 def test_to_EC_KEY(self):
3821 """
3822 The curve object can export a version of itself as an EC_KEY* via the
Alex Chan63ef9bc2016-12-19 12:02:06 +00003823 private `_EllipticCurve._to_EC_KEY`.
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003824 """
3825 curves = get_elliptic_curves()
Alex Chan63ef9bc2016-12-19 12:02:06 +00003826 curve = next(iter(curves))
3827 # It's not easy to assert anything about this object. However, see
3828 # leakcheck/crypto.py for a test that demonstrates it at least does
3829 # not leak memory.
3830 curve._to_EC_KEY()
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003831
3832
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003833class EllipticCurveFactory(object):
3834 """
3835 A helper to get the names of two curves.
3836 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003837
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003838 def __init__(self):
3839 curves = iter(get_elliptic_curves())
Alex Chan63ef9bc2016-12-19 12:02:06 +00003840 self.curve_name = next(curves).name
3841 self.another_curve_name = next(curves).name
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003842
3843
Alex Chan63ef9bc2016-12-19 12:02:06 +00003844class TestEllipticCurveEquality(EqualityTestsMixin):
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003845 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003846 Tests `_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003847 """
3848 curve_factory = EllipticCurveFactory()
3849
3850 if curve_factory.curve_name is None:
3851 skip = "There are no curves available there can be no curve objects."
3852
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003853 def anInstance(self):
3854 """
3855 Get the curve object for an arbitrary curve supported by the system.
3856 """
3857 return get_elliptic_curve(self.curve_factory.curve_name)
3858
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003859 def anotherInstance(self):
3860 """
3861 Get the curve object for an arbitrary curve supported by the system -
3862 but not the one returned by C{anInstance}.
3863 """
3864 return get_elliptic_curve(self.curve_factory.another_curve_name)
3865
3866
Alex Chan63ef9bc2016-12-19 12:02:06 +00003867class TestEllipticCurveHash(object):
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003868 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003869 Tests for `_EllipticCurve`'s implementation of hashing (thus use as
3870 an item in a `dict` or `set`).
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003871 """
3872 curve_factory = EllipticCurveFactory()
3873
3874 if curve_factory.curve_name is None:
3875 skip = "There are no curves available there can be no curve objects."
3876
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003877 def test_contains(self):
3878 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003879 The ``in`` operator reports that a `set` containing a curve does
3880 contain that curve.
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003881 """
3882 curve = get_elliptic_curve(self.curve_factory.curve_name)
3883 curves = set([curve])
Alex Chan63ef9bc2016-12-19 12:02:06 +00003884 assert curve in curves
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003885
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003886 def test_does_not_contain(self):
3887 """
Alex Chan63ef9bc2016-12-19 12:02:06 +00003888 The ``in`` operator reports that a `set` not containing a curve
3889 does not contain that curve.
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003890 """
3891 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003892 curves = set([
3893 get_elliptic_curve(self.curve_factory.another_curve_name)
3894 ])
Alex Chan63ef9bc2016-12-19 12:02:06 +00003895 assert curve not in curves