blob: 03b94b9a70cf95060fec1857fc27d7a9b0a89b4f [file] [log] [blame]
Jean-Paul Calderone8671c852011-03-02 19:26:20 -05001# Copyright (c) Jean-Paul Calderone
2# See LICENSE file for details.
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04003
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05004"""
Jonathan Ballet648875f2011-07-16 14:14:58 +09005Unit tests for :py:mod:`OpenSSL.crypto`.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05006"""
7
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04008from unittest import main
Jean-Paul Calderone60432792015-04-13 12:26:07 -04009from warnings import catch_warnings, simplefilter
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -040010
Alex Gaynor4b9c96a2014-08-14 09:51:48 -070011import base64
12import os
13import re
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -040014from subprocess import PIPE, Popen
Rick Dean47262da2009-07-08 16:17:17 -050015from datetime import datetime, timedelta
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050016
Alex Gaynor791212d2015-09-05 15:46:08 -040017import pytest
18
Alex Gaynorb8e38992015-09-04 08:14:04 -040019from six import u, b, binary_type
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050020
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050021from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050022from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
Alex Gaynor31287502015-09-05 16:11:27 -040023from OpenSSL.crypto import (
24 X509Store, X509StoreType, X509StoreContext, X509StoreContextError
25)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070026from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -050027from OpenSSL.crypto import X509Extension, X509ExtensionType
Rick Dean5b7b6372009-04-01 11:34:06 -050028from OpenSSL.crypto import load_certificate, load_privatekey
Cory Benfield6492f7c2015-10-27 16:57:58 +090029from OpenSSL.crypto import load_publickey, dump_publickey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040030from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040031from OpenSSL.crypto import dump_certificate, load_certificate_request
32from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040033from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Jean-Paul Calderone9178ee62010-01-25 17:55:30 -050034from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
Dominic Chenf05b2122015-10-13 16:32:35 +000035from OpenSSL.crypto import CRL, Revoked, dump_crl, load_crl
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040036from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040037from OpenSSL.crypto import (
38 sign, verify, get_elliptic_curve, get_elliptic_curves)
Hynek Schlawackf0e66852015-10-16 20:18:38 +020039from OpenSSL._util import native, lib
40
41from .util import (
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040042 EqualityTestsMixin, TestCase, WARNING_TYPE_EXPECTED
43)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040044
Alex Gaynoraceb3e22015-09-05 12:00:22 -040045
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -040046def normalize_certificate_pem(pem):
47 return dump_certificate(FILETYPE_PEM, load_certificate(FILETYPE_PEM, pem))
48
49
50def normalize_privatekey_pem(pem):
51 return dump_privatekey(FILETYPE_PEM, load_privatekey(FILETYPE_PEM, pem))
52
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040053
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050054GOOD_CIPHER = "blowfish"
55BAD_CIPHER = "zippers"
56
Anthony Alba2ce737f2015-12-04 11:04:56 +080057GOOD_DIGEST = "SHA1"
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050058BAD_DIGEST = "monkeys"
59
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040060root_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -050061MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
62BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
63ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
64NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
65MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
66ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
67urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
682xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
691dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
70FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
71VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
72BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
73b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
74AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
75hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
76w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
77-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040078""")
Rick Dean94e46fd2009-07-18 14:51:24 -050079
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040080root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -050081MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
82jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
833claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
84AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
85yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
866JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
87BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
88u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
89PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
90I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
91ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
926AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
93cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
94-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -040095""")
Rick Dean94e46fd2009-07-18 14:51:24 -050096
Stephen Holsapple0d9815f2014-08-27 19:36:53 -070097intermediate_cert_pem = b("""-----BEGIN CERTIFICATE-----
98MIICVzCCAcCgAwIBAgIRAMPzhm6//0Y/g2pmnHR2C4cwDQYJKoZIhvcNAQENBQAw
99WDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAw
100DgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwHhcNMTQw
101ODI4MDIwNDA4WhcNMjQwODI1MDIwNDA4WjBmMRUwEwYDVQQDEwxpbnRlcm1lZGlh
102dGUxDDAKBgNVBAoTA29yZzERMA8GA1UECxMIb3JnLXVuaXQxCzAJBgNVBAYTAlVT
103MQswCQYDVQQIEwJDQTESMBAGA1UEBxMJU2FuIERpZWdvMIGfMA0GCSqGSIb3DQEB
104AQUAA4GNADCBiQKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmK
105FGIbljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT
10621H2qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwID
107AQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAPIWSkLX
108QRMApOjjyC+tMxumT5e2pMqChHmxobQK4NMdrf2VCx+cRT6EmY8sK3/Xl/X8UBQ+
1099n5zXb1ZwhW/sTWgUvmOceJ4/XVs9FkdWOOn1J0XBch9ZIiFe/s5ASIgG7fUdcUF
1109mAWS6FK2ca3xIh5kIupCXOFa0dPvlw/YUFT
111-----END CERTIFICATE-----
112""")
113
114intermediate_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
115MIICWwIBAAKBgQDYcEQw5lfbEQRjr5Yy4yxAHGV0b9Al+Lmu7wLHMkZ/ZMmKFGIb
116ljbviiD1Nz97Oh2cpB91YwOXOTN2vXHq26S+A5xe8z/QJbBsyghMur88CjdT21H2
117qwMa+r5dCQwEhuGIiZ3KbzB/n4DTMYI5zy4IYPv0pjxShZn4aZTCCK2IUwIDAQAB
118AoGAfSZVV80pSeOKHTYfbGdNY/jHdU9eFUa/33YWriXU+77EhpIItJjkRRgivIfo
119rhFJpBSGmDLblaqepm8emsXMeH4+2QzOYIf0QGGP6E6scjTt1PLqdqKfVJ1a2REN
120147cujNcmFJb/5VQHHMpaPTgttEjlzuww4+BCDPsVRABWrkCQQD3loH36nLoQTtf
121+kQq0T6Bs9/UWkTAGo0ND81ALj0F8Ie1oeZg6RNT96RxZ3aVuFTESTv6/TbjWywO
122wdzlmV1vAkEA38rTJ6PTwaJlw5OttdDzAXGPB9tDmzh9oSi7cHwQQXizYd8MBYx4
123sjHUKD3dCQnb1dxJFhd3BT5HsnkRMbVZXQJAbXduH17ZTzcIOXc9jHDXYiFVZV5D
12452vV0WCbLzVCZc3jMrtSUKa8lPN5EWrdU3UchWybyG0MR5mX8S5lrF4SoQJAIyUD
125DBKaSqpqONCUUx1BTFS9FYrFjzbL4+c1qHCTTPTblt8kUCrDOZjBrKAqeiTmNSum
126/qUot9YUBF8m6BuGsQJATHHmdFy/fG1VLkyBp49CAa8tN3Z5r/CgTznI4DfMTf4C
127NbRHn2UmYlwQBa+L5lg9phewNe8aEwpPyPLoV85U8Q==
128-----END RSA PRIVATE KEY-----
129""")
130
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400131server_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500132MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
133BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
134VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
135NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
136gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
137lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
138b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
139lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
140gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
141dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
1422mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
143uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
144-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400145""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500146
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400147server_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500148MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
149U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
150SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
151AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
152j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
153j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
154Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
155msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
156FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
1574e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
1581sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
159NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
160r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
161-----END RSA PRIVATE KEY-----
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -0400162"""))
Rick Dean94e46fd2009-07-18 14:51:24 -0500163
Stephen Holsapple0d9815f2014-08-27 19:36:53 -0700164intermediate_server_cert_pem = b("""-----BEGIN CERTIFICATE-----
165MIICWDCCAcGgAwIBAgIRAPQFY9jfskSihdiNSNdt6GswDQYJKoZIhvcNAQENBQAw
166ZjEVMBMGA1UEAxMMaW50ZXJtZWRpYXRlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
167CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
168biBEaWVnbzAeFw0xNDA4MjgwMjEwNDhaFw0yNDA4MjUwMjEwNDhaMG4xHTAbBgNV
169BAMTFGludGVybWVkaWF0ZS1zZXJ2aWNlMQwwCgYDVQQKEwNvcmcxETAPBgNVBAsT
170CG9yZy11bml0MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNh
171biBEaWVnbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqpJZygd+w1faLOr1
172iOAmbBhx5SZWcTCZ/ZjHQTJM7GuPT624QkqsixFghRKdDROwpwnAP7gMRukLqiy4
173+kRuGT5OfyGggL95i2xqA+zehjj08lSTlvGHpePJgCyTavIy5+Ljsj4DKnKyuhxm
174biXTRrH83NDgixVkObTEmh/OVK0CAwEAATANBgkqhkiG9w0BAQ0FAAOBgQBa0Npw
175UkzjaYEo1OUE1sTI6Mm4riTIHMak4/nswKh9hYup//WVOlr/RBSBtZ7Q/BwbjobN
1763bfAtV7eSAqBsfxYXyof7G1ALANQERkq3+oyLP1iVt08W1WOUlIMPhdCF/QuCwy6
177x9MJLhUCGLJPM+O2rAPWVD9wCmvq10ALsiH3yA==
178-----END CERTIFICATE-----
179""")
180
181intermediate_server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
182MIICXAIBAAKBgQCqklnKB37DV9os6vWI4CZsGHHlJlZxMJn9mMdBMkzsa49PrbhC
183SqyLEWCFEp0NE7CnCcA/uAxG6QuqLLj6RG4ZPk5/IaCAv3mLbGoD7N6GOPTyVJOW
1848Yel48mALJNq8jLn4uOyPgMqcrK6HGZuJdNGsfzc0OCLFWQ5tMSaH85UrQIDAQAB
185AoGAIQ594j5zna3/9WaPsTgnmhlesVctt4AAx/n827DA4ayyuHFlXUuVhtoWR5Pk
1865ezj9mtYW8DyeCegABnsu2vZni/CdvU6uiS1Hv6qM1GyYDm9KWgovIP9rQCDSGaz
187d57IWVGxx7ODFkm3gN5nxnSBOFVHytuW1J7FBRnEsehRroECQQDXHFOv82JuXDcz
188z3+4c74IEURdOHcbycxlppmK9kFqm5lsUdydnnGW+mvwDk0APOB7Wg7vyFyr393e
189dpmBDCzNAkEAyv6tVbTKUYhSjW+QhabJo896/EqQEYUmtMXxk4cQnKeR/Ao84Rkf
190EqD5IykMUfUI0jJU4DGX+gWZ10a7kNbHYQJAVFCuHNFxS4Cpwo0aqtnzKoZaHY/8
191X9ABZfafSHCtw3Op92M+7ikkrOELXdS9KdKyyqbKJAKNEHF3LbOfB44WIQJAA2N4
1929UNNVUsXRbElEnYUS529CdUczo4QdVgQjkvk5RiPAUwSdBd9Q0xYnFOlFwEmIowg
193ipWJWe0aAlP18ZcEQQJBAL+5lekZ/GUdQoZ4HAsN5a9syrzavJ9VvU1KOOPorPZK
194nMRZbbQgP+aSB7yl6K0gaLaZ8XaK0pjxNBh6ASqg9f4=
195-----END RSA PRIVATE KEY-----
196""")
197
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400198client_cert_pem = b("""-----BEGIN CERTIFICATE-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500199MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
200BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
201VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
202ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
203MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
204rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
205iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
206oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
2070fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
208Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
2099Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
210PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
211-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400212""")
Rick Dean94e46fd2009-07-18 14:51:24 -0500213
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400214client_key_pem = normalize_privatekey_pem(b("""-----BEGIN RSA PRIVATE KEY-----
Rick Dean94e46fd2009-07-18 14:51:24 -0500215MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
216btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
217eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
218AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
219zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
220h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
221V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
222TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
223dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
224D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
225si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
226JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
227f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
228-----END RSA PRIVATE KEY-----
Jean-Paul Calderone22cbe502011-05-04 17:01:43 -0400229"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400230
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400231cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400232MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
233BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
234ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
235NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
236MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
237ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
238urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
2392xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
2401dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
241FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
242VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
243BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
244b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
245AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
246hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
247w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
248-----END CERTIFICATE-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400249""")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400250
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400251cleartextPrivateKeyPEM = normalize_privatekey_pem(b("""\
252-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400253MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
254jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
2553claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
256AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
257yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
2586JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
259BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
260u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
261PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
262I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
263ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
2646AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
265cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
266-----END RSA PRIVATE KEY-----
Jean-Paul Calderoned50d2042011-05-04 17:00:49 -0400267"""))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400268
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400269cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
270MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
271EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
272ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
273BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
274E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
275xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
276gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
277Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
278oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
279-----END CERTIFICATE REQUEST-----
280""")
Rick Dean5b7b6372009-04-01 11:34:06 -0500281
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400282encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400283Proc-Type: 4,ENCRYPTED
284DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400285
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400286SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
287a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
2888+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
289mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
290+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
291fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
292tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
293rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
294gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
295o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
2967SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
297MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
29811n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
299-----END RSA PRIVATE KEY-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400300""")
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400301
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400302encryptedPrivateKeyPEMPassphrase = b("foobar")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400303
Cory Benfield6492f7c2015-10-27 16:57:58 +0900304
305cleartextPublicKeyPEM = b("""-----BEGIN PUBLIC KEY-----
306MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/l
307gT/JzSVJtnEqw9WUNGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC
30890qlUxI47vNJbXGRfmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+
309ceg1v01yCT2+OjhQW3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5
310XIneGUpX1S7mXRxTLH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS
3118Xk5iKICEXwnZreIt3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhL
312ywIDAQAB
313-----END PUBLIC KEY-----
314""")
315
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400316# Some PKCS#7 stuff. Generated with the openssl command line:
317#
318# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
319#
320# with a certificate and key (but the key should be irrelevant) in s.pem
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400321pkcs7Data = b("""\
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400322-----BEGIN PKCS7-----
323MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
324BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
325A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
326MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
327cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
328A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
329HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
330SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
331zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
332LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
333A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
33465w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
335Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
336Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
337bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
338VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
339/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
340Ho4EzbYCOaEAMQA=
341-----END PKCS7-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400342""")
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400343
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700344pkcs7DataASN1 = base64.b64decode(b"""
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700345MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
346BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
347A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
348MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
349cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
350A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
351HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
352SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
353zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
354LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
355A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
35665w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
357Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
358Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
359bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
360VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
361/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
362Ho4EzbYCOaEAMQA=
Alex Gaynor8fa1dd62014-08-14 09:57:51 -0700363""")
Alex Gaynor4b9c96a2014-08-14 09:51:48 -0700364
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400365crlData = b("""\
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -0500366-----BEGIN X509 CRL-----
367MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
368SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
369D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
370MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
371MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
3724dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
3730yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
374vrzEeLDRiiPl92dyyWmu
375-----END X509 CRL-----
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400376""")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -0400377
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400378
379# A broken RSA private key which can be used to test the error path through
380# PKey.check.
381inconsistentPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
382MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
3835kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEaAQJBAIqm/bz4NA1H++Vx5Ewx
384OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
385zIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
386nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
387HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNeH+vRWsAYU/gbx+OQB+7VOcBAiEA
388oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
389-----END RSA PRIVATE KEY-----
390""")
391
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400392# certificate with NULL bytes in subjectAltName and common name
393
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -0400394nulbyteSubjectAltNamePEM = b("""-----BEGIN CERTIFICATE-----
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -0400395MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
396DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
397eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
398RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
399ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
400NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
401DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
402ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
403ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
404hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
405BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
406pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
407vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
408KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
409oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
41008LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
411HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
412BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
413Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
414bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
415AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
416i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
417HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
418kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
419VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
420RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
421-----END CERTIFICATE-----""")
422
Colleen Murphye09399b2016-03-01 17:40:49 -0800423large_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
424MIIJYgIBAAKCAg4AtRua8eIeevRfsj+fkcHr1vmse7Kgb+oX1ssJAvCb1R7JQMnH
425hNDjDP6b3vEkZuPUzlDHymP+cNkXvvi4wJ4miVbO3+SeU4Sh+jmsHeHzGIXat9xW
4269PFtuPM5FQq8zvkY8aDeRYmYwN9JKu4/neMBCBqostYlTEWg+bSytO/qWnyHTHKh
427g0GfaDdqUQPsGQw+J0MgaYIjQOCVASHAPlzbDQLCtuOb587rwTLkZA2GwoHB/LyJ
428BwT0HHgBaiObE12Vs6wi2en0Uu11CiwEuK1KIBcZ2XbE6eApaZa6VH9ysEmUxPt7
429TqyZ4E2oMIYaLPNRxuvozdwTlj1svI1k1FrkaXGc5MTjbgigPMKjIb0T7b/4GNzt
430DhP1LvAeUMnrEi3hJJrcJPXHPqS8/RiytR9xQQW6Sdh4LaA3f9MQm3WSevWage3G
431P8YcCLssOVKsArDjuA52NF5LmYuAeUzXprm4ITDi2oO+0iFBpFW6VPEK4A9vO0Yk
432M/6Wt6tG8zyWhaSH1zFUTwfQ9Yvjyt5w1lrUaAJuoTpwbMVZaDJaEhjOaXU0dyPQ
433jOsePDOQcU6dkeTWsQ3LsHPEEug/X6819TLG5mb3V7bvV9nPFBfTJSCEG794kr90
434XgZfIN71FrdByxLerlbuJI21pPs/nZi9SXi9jAWeiS45/azUxMsyYgJArui+gjq7
435sV1pWiBm6/orAgMBAAECggINQp5L6Yu+oIXBqcSjgq8tfF9M5hd30pLuf/EheHZf
436LA7uAqn2fVGFI2OInIJhXIOT5OxsAXO0xXfltzawZxIFpOFMqajj4F7aYjvSpw9V
437J4EdSiJ/zgv8y1qUdbwEZbHVThRZjoSlrtSzilonBoHZAE0mHtqMz7iRFSk1zz6t
438GunRrvo/lROPentf3TsvHquVNUYI5yaapyO1S7xJhecMIIYSb8nbsHI54FBDGNas
4396mFmpPwI/47/6HTwOEWupnn3NicsjrHzUInOUpaMig4cRR+aP5bjqg/ty8xI8AoN
440evEmCytiWTc+Rvbp1ieN+1jpjN18PjUk80/W7qioHUDt4ieLic8uxWH2VD9SCEnX
441Mpi9tA/FqoZ+2A/3m1OfrY6jiZVE2g+asi9lCK7QVWL39eK82H4rPvtp0/dyo1/i
442ZZz68TXg+m8IgEZcp88hngbkuoTTzpGE73QuPKhGA1uMIimDdqPPB5WP76q+03Oi
443IRR5DfZnqPERed49by0enJ7tKa/gFPZizOV8ALKr0Dp+vfAkxGDLPLBLd2A3//tw
444xg0Q/wltihHSBujv4nYlDXdc5oYyMYZ+Lhc/VuOghHfBq3tgEQ1ECM/ofqXEIdy7
445nVcpZn3Eeq8Jl5CrqxE1ee3NxlzsJHn99yGQpr7mOhW/psJF3XNz80Meg3L4m1T8
446sMBK0GbaassuJhdzb5whAoIBBw48sx1b1WR4XxQc5O/HjHva+l16i2pjUnOUTcDF
447RWmSbIhBm2QQ2rVhO8+fak0tkl6ZnMWW4i0U/X5LOEBbC7+IS8bO3j3Revi+Vw5x
448j96LMlIe9XEub5i/saEWgiz7maCvfzLFU08e1OpT4qPDpP293V400ubA6R7WQTCv
449pBkskGwHeu0l/TuKkVqBFFUTu7KEbps8Gjg7MkJaFriAOv1zis/umK8pVS3ZAM6e
4508w5jfpRccn8Xzta2fRwTB5kCmfxdDsY0oYGxPLRAbW72bORoLGuyyPp/ojeGwoik
451JX9RttErc6FjyZtks370Pa8UL5QskyhMbDhrZW2jFD+RXYM1BrvmZRjbAoIBBwy4
452iFJpuDfytJfz1MWtaL5DqEL/kmiZYAXl6hifNhGu5GAipVIIGsDqEYW4i+VC15aa
4537kOCwz/I5zsB3vSDW96IRs4wXtqEZSibc2W/bqfVi+xcvPPl1ZhQ2EAwa4D/x035
454kyf20ffWOU+1yf2cnijzqs3IzlveUm+meLw5s3Rc+iG7DPWWeCoe1hVwANI1euNc
455pqKwKY905yFyjOje2OgiEU2kS4YME4zGeBys8yo7E42hNnN2EPK6xkkUqzdudLLQ
4568OUlKRTc8AbIf3XG1rpA4VUpTv3hhxGGwCRy6If8zgZQsNYchgNztRGk72Gcb8Dm
457vFSEN3ZtwxU64G3YZzntdcr2WPzxAoIBBw30g6Fgdb/gmVnOpL0//T0ePNDKIMPs
458jVJLaRduhoZgB1Bb9qPUPX0SzRzLZtg1tkZSDjBDoHmOHJfhxUaXt+FLCPPbrE4t
459+nq9n/nBaMM779w9ClqhqLOyGrwKoxjSmhi+TVEHyIxCbXMvPHVHfX9WzxjbcGrN
460ZvRaEVZWo+QlIX8yqdSwqxLk1WtAIRzvlcj7NKum8xBxPed6BNFep/PtgIAmoLT5
461L8wb7EWb2iUdc2KbZ4OaY51lDScqpATgXu3WjXfM+Q52G0mX6Wyd0cjlL711Zrjb
462yLbiueZT94lgIHHRRKtKc8CEqcjkQV5OzABS3P/gQSfgZXBdLKjOpTnKDUq7IBeH
463AoIBBweAOEIAPLQg1QRUrr3xRrYKRwlakgZDii9wJt1l5AgBTICzbTA1vzDJ1JM5
464AqSpCV6w9JWyYVcXK+HLdKBRZLaPPNEQDJ5lOxD6uMziWGl2rg8tj+1xNMWfxiPz
465aTCjoe4EoBUMoTq2gwzRcM2usEQNikXVhnj9Wzaivsaeb4bJ3GRPW5DkrO6JSEtT
466w+gvyMqQM2Hy5k7E7BT46sXVwaj/jZxuqGnebRixXtnp0WixdRIqYWUr1UqLf6hQ
467G7WP2BgoxCMaCmNW8+HMD/xuxucEotoIhZ+GgJKBFoNnjl3BX+qxYdSe9RbL/5Tr
4684It6Jxtj8uETJXEbv9Cg6v1agWPS9YY8RLTBAoIBBwrU2AsAUts6h1LgGLKK3UWZ
469oLH5E+4o+7HqSGRcRodVeN9NBXIYdHHOLeEG6YNGJiJ3bFP5ZQEu9iDsyoFVKJ9O
470Mw/y6dKZuxOCZ+X8FopSROg3yWfdOpAm6cnQZp3WqLNX4n/Q6WvKojfyEiPphjwT
4710ymrUJELXLWJmjUyPoAk6HgC0Gs28ZnEXbyhx7CSbZNFyCU/PNUDZwto3GisIPD3
472le7YjqHugezmjMGlA0sDw5aCXjfbl74vowRFYMO6e3ItApfSRgNV86CDoX74WI/5
473AYU/QVM4wGt8XGT2KwDFJaxYGKsGDMWmXY04dS+WPuetCbouWUusyFwRb9SzFave
474vYeU7Ab/
475-----END RSA PRIVATE KEY-----""")
476
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400477
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400478class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400479 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900480 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400481 """
482
483 def setUp(self):
484 """
485 Create a new private key and start a certificate request (for a test
486 method to finish in one way or another).
487 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800488 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400489 # Basic setup stuff to generate a certificate
490 self.pkey = PKey()
491 self.pkey.generate_key(TYPE_RSA, 384)
492 self.req = X509Req()
493 self.req.set_pubkey(self.pkey)
494 # Authority good you have.
495 self.req.get_subject().commonName = "Yoda root CA"
496 self.x509 = X509()
497 self.subject = self.x509.get_subject()
498 self.subject.commonName = self.req.get_subject().commonName
499 self.x509.set_issuer(self.subject)
500 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400501 now = datetime.now()
502 expire = datetime.now() + timedelta(days=100)
503 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
504 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400505
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800506 def tearDown(self):
507 """
508 Forget all of the pyOpenSSL objects so they can be garbage collected,
509 their memory released, and not interfere with the leak detection code.
510 """
511 self.pkey = self.req = self.x509 = self.subject = None
512 super(X509ExtTests, self).tearDown()
513
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400514 def test_str(self):
515 """
Alex Gaynor31287502015-09-05 16:11:27 -0400516 The string representation of :py:class:`X509Extension` instances as
517 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400518 """
519 # This isn't necessarily the best string representation. Perhaps it
520 # will be changed/improved in the future.
521 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400522 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400523 'CA:FALSE')
524
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400525 def test_type(self):
526 """
Alex Gaynor31287502015-09-05 16:11:27 -0400527 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
528 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400529 """
530 self.assertIdentical(X509Extension, X509ExtensionType)
531 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400532 X509Extension,
533 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400534
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500535 def test_construction(self):
536 """
Alex Gaynor31287502015-09-05 16:11:27 -0400537 :py:class:`X509Extension` accepts an extension type name, a critical
538 flag, and an extension value and returns an
539 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500540 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400541 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500542 self.assertTrue(
543 isinstance(basic, X509ExtensionType),
544 "%r is of type %r, should be %r" % (
545 basic, type(basic), X509ExtensionType))
546
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400547 comment = X509Extension(
548 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500549 self.assertTrue(
550 isinstance(comment, X509ExtensionType),
551 "%r is of type %r, should be %r" % (
552 comment, type(comment), X509ExtensionType))
553
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500554 def test_invalid_extension(self):
555 """
Alex Gaynor31287502015-09-05 16:11:27 -0400556 :py:class:`X509Extension` raises something if it is passed a bad
557 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500558 """
559 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400560 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500561 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400562 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500563
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500564 # Exercise a weird one (an extension which uses the r2i method). This
565 # exercises the codepath that requires a non-NULL ctx to be passed to
566 # X509V3_EXT_nconf. It can't work now because we provide no
567 # configuration database. It might be made to work in the future.
568 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400569 Error, X509Extension, b('proxyCertInfo'), True,
570 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500571
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500572 def test_get_critical(self):
573 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900574 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500575 extension's critical flag.
576 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400577 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500578 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400579 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500580 self.assertFalse(ext.get_critical())
581
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500582 def test_get_short_name(self):
583 """
Alex Gaynor31287502015-09-05 16:11:27 -0400584 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
585 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500586 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400587 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
588 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
589 ext = X509Extension(b('nsComment'), True, b('foo bar'))
590 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500591
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400592 def test_get_data(self):
593 """
Alex Gaynor31287502015-09-05 16:11:27 -0400594 :py:meth:`X509Extension.get_data` returns a string giving the data of
595 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400596 """
597 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
598 # Expect to get back the DER encoded form of CA:true.
599 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
600
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400601 def test_get_data_wrong_args(self):
602 """
Alex Gaynor31287502015-09-05 16:11:27 -0400603 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
604 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400605 """
606 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
607 self.assertRaises(TypeError, ext.get_data, None)
608 self.assertRaises(TypeError, ext.get_data, "foo")
609 self.assertRaises(TypeError, ext.get_data, 7)
610
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400611 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500612 """
Alex Gaynor31287502015-09-05 16:11:27 -0400613 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
614 provided for an extension which does not use it and is ignored in this
615 case.
Rick Dean47262da2009-07-08 16:17:17 -0500616 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400617 ext1 = X509Extension(
618 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400619 self.x509.add_extensions([ext1])
620 self.x509.sign(self.pkey, 'sha1')
621 # This is a little lame. Can we think of a better way?
622 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400623 self.assertTrue(b('X509v3 Basic Constraints:') in text)
624 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400625
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400626 def test_subject(self):
627 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900628 If an extension requires a subject, the :py:data:`subject` parameter to
629 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400630 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400631 ext3 = X509Extension(
632 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400633 self.x509.add_extensions([ext3])
634 self.x509.sign(self.pkey, 'sha1')
635 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400636 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400637
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400638 def test_missing_subject(self):
639 """
Alex Gaynor31287502015-09-05 16:11:27 -0400640 If an extension requires a subject and the :py:data:`subject` parameter
641 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400642 """
643 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400644 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400645
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400646 def test_invalid_subject(self):
647 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900648 If the :py:data:`subject` parameter is given a value which is not an
649 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400650 """
651 for badObj in [True, object(), "hello", [], self]:
652 self.assertRaises(
653 TypeError,
654 X509Extension,
655 'basicConstraints', False, 'CA:TRUE', subject=badObj)
656
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400657 def test_unused_issuer(self):
658 """
Alex Gaynor31287502015-09-05 16:11:27 -0400659 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
660 provided for an extension which does not use it and is ignored in this
661 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400662 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400663 ext1 = X509Extension(
664 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400665 self.x509.add_extensions([ext1])
666 self.x509.sign(self.pkey, 'sha1')
667 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400668 self.assertTrue(b('X509v3 Basic Constraints:') in text)
669 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400670
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400671 def test_issuer(self):
672 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800673 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900674 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400675 """
676 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400677 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400678 issuer=self.x509)
679 self.x509.add_extensions([ext2])
680 self.x509.sign(self.pkey, 'sha1')
681 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400682 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
683 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400684
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400685 def test_missing_issuer(self):
686 """
Alex Gaynor31287502015-09-05 16:11:27 -0400687 If an extension requires an issue and the :py:data:`issuer` parameter
688 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400689 """
690 self.assertRaises(
691 Error,
692 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400693 b('authorityKeyIdentifier'), False,
694 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400695
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400696 def test_invalid_issuer(self):
697 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900698 If the :py:data:`issuer` parameter is given a value which is not an
699 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400700 """
701 for badObj in [True, object(), "hello", [], self]:
702 self.assertRaises(
703 TypeError,
704 X509Extension,
705 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
706 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500707
708
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400709class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500710 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900711 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500712 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400713
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400714 def test_type(self):
715 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900716 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
717 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400718 """
719 self.assertIdentical(PKey, PKeyType)
720 self.assertConsistentType(PKey, 'PKey')
721
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500722 def test_construction(self):
723 """
Alex Gaynor31287502015-09-05 16:11:27 -0400724 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
725 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500726 """
727 self.assertRaises(TypeError, PKey, None)
728 key = PKey()
729 self.assertTrue(
730 isinstance(key, PKeyType),
731 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
732
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500733 def test_pregeneration(self):
734 """
Alex Gaynor31287502015-09-05 16:11:27 -0400735 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
736 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
737 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500738 """
739 key = PKey()
740 self.assertEqual(key.type(), 0)
741 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400742 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500743
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500744 def test_failedGeneration(self):
745 """
Alex Gaynor31287502015-09-05 16:11:27 -0400746 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
747 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
748 the second giving the number of bits to generate. If an invalid type
749 is specified or generation fails, :py:exc:`Error` is raised. If an
750 invalid number of bits is specified, :py:exc:`ValueError` or
751 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500752 """
753 key = PKey()
754 self.assertRaises(TypeError, key.generate_key)
755 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
756 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
757 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500758
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500759 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
760 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500761
762 # XXX RSA generation for small values of bits is fairly buggy in a wide
763 # range of OpenSSL versions. I need to figure out what the safe lower
764 # bound for a reasonable number of OpenSSL versions is and explicitly
765 # check for that in the wrapper. The failure behavior is typically an
766 # infinite loop inside OpenSSL.
767
768 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500769
770 # XXX DSA generation seems happy with any number of bits. The DSS
771 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
772 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500773 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500774 # So, it doesn't seem possible to make generate_key fail for
775 # TYPE_DSA with a bits argument which is at least an int.
776
777 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
778
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500779 def test_rsaGeneration(self):
780 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900781 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
782 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500783 """
784 bits = 128
785 key = PKey()
786 key.generate_key(TYPE_RSA, bits)
787 self.assertEqual(key.type(), TYPE_RSA)
788 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400789 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500790
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500791 def test_dsaGeneration(self):
792 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900793 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
794 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500795 """
796 # 512 is a magic number. The DSS (Digital Signature Standard)
797 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
798 # will silently promote any value below 512 to 512.
799 bits = 512
800 key = PKey()
801 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800802 # self.assertEqual(key.type(), TYPE_DSA)
803 # self.assertEqual(key.bits(), bits)
804 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500805
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500806 def test_regeneration(self):
807 """
Alex Gaynor31287502015-09-05 16:11:27 -0400808 :py:meth:`PKeyType.generate_key` can be called multiple times on the
809 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500810 """
811 key = PKey()
812 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400813 key.generate_key(type, bits)
814 self.assertEqual(key.type(), type)
815 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500816
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400817 def test_inconsistentKey(self):
818 """
Alex Gaynor31287502015-09-05 16:11:27 -0400819 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
820 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400821 """
822 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400823 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400824
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400825 def test_check_wrong_args(self):
826 """
Alex Gaynor31287502015-09-05 16:11:27 -0400827 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
828 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400829 """
830 self.assertRaises(TypeError, PKey().check, None)
831 self.assertRaises(TypeError, PKey().check, object())
832 self.assertRaises(TypeError, PKey().check, 1)
833
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400834 def test_check_public_key(self):
835 """
836 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
837 part of the key is available.
838 """
839 # A trick to get a public-only key
840 key = PKey()
841 key.generate_key(TYPE_RSA, 512)
842 cert = X509()
843 cert.set_pubkey(key)
844 pub = cert.get_pubkey()
845 self.assertRaises(TypeError, pub.check)
846
847
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400848class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500849 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900850 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500851 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400852
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500853 def _x509name(self, **attrs):
854 # XXX There's no other way to get a new X509Name yet.
855 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400856 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400857
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500858 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400859 def key(attr):
860 return attr[1]
861 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500862 for k, v in attrs:
863 setattr(name, k, v)
864 return name
865
Rick Deane15b1472009-07-09 15:53:42 -0500866 def test_type(self):
867 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900868 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500869 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400870 self.assertIdentical(X509Name, X509NameType)
871 self.assertEqual(X509NameType.__name__, 'X509Name')
872 self.assertTrue(isinstance(X509NameType, type))
873
Rick Deane15b1472009-07-09 15:53:42 -0500874 name = self._x509name()
875 self.assertTrue(
876 isinstance(name, X509NameType),
877 "%r is of type %r, should be %r" % (
878 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500879
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400880 def test_onlyStringAttributes(self):
881 """
Alex Gaynor31287502015-09-05 16:11:27 -0400882 Attempting to set a non-:py:data:`str` attribute name on an
883 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
884 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400885 """
886 name = self._x509name()
887 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400888 # rejected. Sorry, you're wrong. unicode is automatically converted
889 # to str outside of the control of X509Name, so there's no way to
890 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800891
Alex Gaynor31287502015-09-05 16:11:27 -0400892 # Also, this used to test str subclasses, but that test is less
893 # relevant now that the implementation is in Python instead of C. Also
894 # PyPy automatically converts str subclasses to str when they are
895 # passed to setattr, so we can't test it on PyPy. Apparently CPython
896 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400897 self.assertRaises(TypeError, setattr, name, None, "hello")
898 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400899
900 def test_setInvalidAttribute(self):
901 """
Alex Gaynor31287502015-09-05 16:11:27 -0400902 Attempting to set any attribute name on an :py:class:`X509NameType`
903 instance for which no corresponding NID is defined causes
904 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400905 """
906 name = self._x509name()
907 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
908
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500909 def test_attributes(self):
910 """
Alex Gaynor31287502015-09-05 16:11:27 -0400911 :py:class:`X509NameType` instances have attributes for each standard
912 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500913 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500914 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500915 name.commonName = "foo"
916 self.assertEqual(name.commonName, "foo")
917 self.assertEqual(name.CN, "foo")
918 name.CN = "baz"
919 self.assertEqual(name.commonName, "baz")
920 self.assertEqual(name.CN, "baz")
921 name.commonName = "bar"
922 self.assertEqual(name.commonName, "bar")
923 self.assertEqual(name.CN, "bar")
924 name.CN = "quux"
925 self.assertEqual(name.commonName, "quux")
926 self.assertEqual(name.CN, "quux")
927
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500928 def test_copy(self):
929 """
Alex Gaynor31287502015-09-05 16:11:27 -0400930 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
931 with all the same attributes as an existing :py:class:`X509NameType`
932 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500933 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500934 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500935
936 copy = X509Name(name)
937 self.assertEqual(copy.commonName, "foo")
938 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500939
940 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500941 copy.commonName = "baz"
942 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500943
944 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500945 name.emailAddress = "quux@example.com"
946 self.assertEqual(copy.emailAddress, "bar@example.com")
947
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500948 def test_repr(self):
949 """
Alex Gaynor31287502015-09-05 16:11:27 -0400950 :py:func:`repr` passed an :py:class:`X509NameType` instance should
951 return a string containing a description of the type and the NIDs which
952 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500953 """
954 name = self._x509name(commonName="foo", emailAddress="bar")
955 self.assertEqual(
956 repr(name),
957 "<X509Name object '/emailAddress=bar/CN=foo'>")
958
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500959 def test_comparison(self):
960 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900961 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500962 """
963 def _equality(a, b, assertTrue, assertFalse):
964 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
965 assertFalse(a != b)
966 assertTrue(b == a)
967 assertFalse(b != a)
968
969 def assertEqual(a, b):
970 _equality(a, b, self.assertTrue, self.assertFalse)
971
972 # Instances compare equal to themselves.
973 name = self._x509name()
974 assertEqual(name, name)
975
976 # Empty instances should compare equal to each other.
977 assertEqual(self._x509name(), self._x509name())
978
979 # Instances with equal NIDs should compare equal to each other.
980 assertEqual(self._x509name(commonName="foo"),
981 self._x509name(commonName="foo"))
982
983 # Instance with equal NIDs set using different aliases should compare
984 # equal to each other.
985 assertEqual(self._x509name(commonName="foo"),
986 self._x509name(CN="foo"))
987
988 # Instances with more than one NID with the same values should compare
989 # equal to each other.
990 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
991 self._x509name(commonName="foo", OU="bar"))
992
993 def assertNotEqual(a, b):
994 _equality(a, b, self.assertFalse, self.assertTrue)
995
996 # Instances with different values for the same NID should not compare
997 # equal to each other.
998 assertNotEqual(self._x509name(CN="foo"),
999 self._x509name(CN="bar"))
1000
1001 # Instances with different NIDs should not compare equal to each other.
1002 assertNotEqual(self._x509name(CN="foo"),
1003 self._x509name(OU="foo"))
1004
1005 def _inequality(a, b, assertTrue, assertFalse):
1006 assertTrue(a < b)
1007 assertTrue(a <= b)
1008 assertTrue(b > a)
1009 assertTrue(b >= a)
1010 assertFalse(a > b)
1011 assertFalse(a >= b)
1012 assertFalse(b < a)
1013 assertFalse(b <= a)
1014
1015 def assertLessThan(a, b):
1016 _inequality(a, b, self.assertTrue, self.assertFalse)
1017
1018 # An X509Name with a NID with a value which sorts less than the value
1019 # of the same NID on another X509Name compares less than the other
1020 # X509Name.
1021 assertLessThan(self._x509name(CN="abc"),
1022 self._x509name(CN="def"))
1023
1024 def assertGreaterThan(a, b):
1025 _inequality(a, b, self.assertFalse, self.assertTrue)
1026
1027 # An X509Name with a NID with a value which sorts greater than the
1028 # value of the same NID on another X509Name compares greater than the
1029 # other X509Name.
1030 assertGreaterThan(self._x509name(CN="def"),
1031 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001032
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001033 def test_hash(self):
1034 """
Alex Gaynor31287502015-09-05 16:11:27 -04001035 :py:meth:`X509Name.hash` returns an integer hash based on the value of
1036 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -04001037 """
1038 a = self._x509name(CN="foo")
1039 b = self._x509name(CN="foo")
1040 self.assertEqual(a.hash(), b.hash())
1041 a.CN = "bar"
1042 self.assertNotEqual(a.hash(), b.hash())
1043
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001044 def test_der(self):
1045 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001046 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001047 """
1048 a = self._x509name(CN="foo", C="US")
1049 self.assertEqual(
1050 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001051 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +02001052 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -04001053
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001054 def test_get_components(self):
1055 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001056 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1057 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001058 giving the NIDs and associated values which make up the name.
1059 """
1060 a = self._x509name()
1061 self.assertEqual(a.get_components(), [])
1062 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001063 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001064 a.organizationalUnitName = "bar"
1065 self.assertEqual(
1066 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001067 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001068
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001069 def test_load_nul_byte_attribute(self):
1070 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001071 An :py:class:`OpenSSL.crypto.X509Name` from an
1072 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001073 NUL byte in the value of one of its attributes.
1074 """
1075 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1076 subject = cert.get_subject()
1077 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001078 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001079
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001080 def test_setAttributeFailure(self):
1081 """
1082 If the value of an attribute cannot be set for some reason then
1083 :py:class:`OpenSSL.crypto.Error` is raised.
1084 """
1085 name = self._x509name()
1086 # This value is too long
1087 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1088
1089
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001090class _PKeyInteractionTestsMixin:
1091 """
1092 Tests which involve another thing and a PKey.
1093 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001094
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001095 def signable(self):
1096 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001097 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1098 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001099 """
1100 raise NotImplementedError()
1101
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001102 def test_signWithUngenerated(self):
1103 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001104 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1105 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001106 """
1107 request = self.signable()
1108 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001109 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001110
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001111 def test_signWithPublicKey(self):
1112 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001113 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1114 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001115 """
1116 request = self.signable()
1117 key = PKey()
1118 key.generate_key(TYPE_RSA, 512)
1119 request.set_pubkey(key)
1120 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001121 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001122
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001123 def test_signWithUnknownDigest(self):
1124 """
Alex Gaynor31287502015-09-05 16:11:27 -04001125 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1126 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001127 """
1128 request = self.signable()
1129 key = PKey()
1130 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001131 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001132
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001133 def test_sign(self):
1134 """
Alex Gaynor31287502015-09-05 16:11:27 -04001135 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1136 valid digest function. :py:meth:`X509Req.verify` can be used to check
1137 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001138 """
1139 request = self.signable()
1140 key = PKey()
1141 key.generate_key(TYPE_RSA, 512)
1142 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001143 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001144 # If the type has a verify method, cover that too.
1145 if getattr(request, 'verify', None) is not None:
1146 pub = request.get_pubkey()
1147 self.assertTrue(request.verify(pub))
1148 # Make another key that won't verify.
1149 key = PKey()
1150 key.generate_key(TYPE_RSA, 512)
1151 self.assertRaises(Error, request.verify, key)
1152
1153
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001154class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001155 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001156 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001157 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001158
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001159 def signable(self):
1160 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001161 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001162 """
1163 return X509Req()
1164
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001165 def test_type(self):
1166 """
Alex Gaynor31287502015-09-05 16:11:27 -04001167 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1168 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001169 """
1170 self.assertIdentical(X509Req, X509ReqType)
1171 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001172
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001173 def test_construction(self):
1174 """
Alex Gaynor31287502015-09-05 16:11:27 -04001175 :py:obj:`X509Req` takes no arguments and returns an
1176 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001177 """
1178 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001179 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001180
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001181 def test_version(self):
1182 """
Alex Gaynor31287502015-09-05 16:11:27 -04001183 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1184 certificate request. :py:obj:`X509ReqType.get_version` returns the
1185 X.509 version of the certificate request. The initial value of the
1186 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001187 """
1188 request = X509Req()
1189 self.assertEqual(request.get_version(), 0)
1190 request.set_version(1)
1191 self.assertEqual(request.get_version(), 1)
1192 request.set_version(3)
1193 self.assertEqual(request.get_version(), 3)
1194
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001195 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001196 """
Alex Gaynor31287502015-09-05 16:11:27 -04001197 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1198 with the wrong number of arguments or with a non-:py:obj:`int`
1199 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1200 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001201 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001202 request = X509Req()
1203 self.assertRaises(TypeError, request.set_version)
1204 self.assertRaises(TypeError, request.set_version, "foo")
1205 self.assertRaises(TypeError, request.set_version, 1, 2)
1206 self.assertRaises(TypeError, request.get_version, None)
1207
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001208 def test_get_subject(self):
1209 """
Alex Gaynor31287502015-09-05 16:11:27 -04001210 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1211 subject of the request and which is valid even after the request object
1212 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001213 """
1214 request = X509Req()
1215 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001216 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001217 subject.commonName = "foo"
1218 self.assertEqual(request.get_subject().commonName, "foo")
1219 del request
1220 subject.commonName = "bar"
1221 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001222
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001223 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001224 """
Alex Gaynor31287502015-09-05 16:11:27 -04001225 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1226 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001227 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001228 request = X509Req()
1229 self.assertRaises(TypeError, request.get_subject, None)
1230
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001231 def test_add_extensions(self):
1232 """
Alex Gaynor31287502015-09-05 16:11:27 -04001233 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1234 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001235 """
1236 request = X509Req()
1237 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001238 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001239 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001240 self.assertEqual(len(exts), 1)
1241 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1242 self.assertEqual(exts[0].get_critical(), 1)
1243 self.assertEqual(exts[0].get_data(), b('0\x00'))
1244
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001245 def test_get_extensions(self):
1246 """
1247 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1248 extensions added to this X509 request.
1249 """
1250 request = X509Req()
1251 exts = request.get_extensions()
1252 self.assertEqual(exts, [])
1253 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001254 X509Extension(b('basicConstraints'), True, b('CA:true')),
1255 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001256 exts = request.get_extensions()
1257 self.assertEqual(len(exts), 2)
1258 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1259 self.assertEqual(exts[0].get_critical(), 1)
1260 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1261 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1262 self.assertEqual(exts[1].get_critical(), 0)
1263 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001264
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001265 def test_add_extensions_wrong_args(self):
1266 """
Alex Gaynor31287502015-09-05 16:11:27 -04001267 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1268 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1269 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1270 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001271 """
1272 request = X509Req()
1273 self.assertRaises(TypeError, request.add_extensions)
1274 self.assertRaises(TypeError, request.add_extensions, object())
1275 self.assertRaises(ValueError, request.add_extensions, [object()])
1276 self.assertRaises(TypeError, request.add_extensions, [], None)
1277
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001278 def test_verify_wrong_args(self):
1279 """
1280 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1281 arguments or more than one argument or if passed anything other than a
1282 :py:obj:`PKey` instance as its single argument.
1283 """
1284 request = X509Req()
1285 self.assertRaises(TypeError, request.verify)
1286 self.assertRaises(TypeError, request.verify, object())
1287 self.assertRaises(TypeError, request.verify, PKey(), object())
1288
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001289 def test_verify_uninitialized_key(self):
1290 """
Alex Gaynor31287502015-09-05 16:11:27 -04001291 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1292 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001293 """
1294 request = X509Req()
1295 pkey = PKey()
1296 self.assertRaises(Error, request.verify, pkey)
1297
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001298 def test_verify_wrong_key(self):
1299 """
Alex Gaynor31287502015-09-05 16:11:27 -04001300 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1301 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1302 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001303 """
1304 request = X509Req()
1305 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001306 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001307 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1308 self.assertRaises(Error, request.verify, another_pkey)
1309
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001310 def test_verify_success(self):
1311 """
1312 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001313 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1314 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001315 """
1316 request = X509Req()
1317 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001318 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001319 self.assertEqual(True, request.verify(pkey))
1320
1321
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001322class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001323 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001324 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001325 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001326 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001327
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001328 extpem = """
1329-----BEGIN CERTIFICATE-----
1330MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1331BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1332eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1333MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1334aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1335hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1336Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1337zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1338hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1339TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
134003HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1341MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1342b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1343MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1344uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1345WpOdIpB8KksUTCzV591Nr1wd
1346-----END CERTIFICATE-----
1347 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001348
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001349 def signable(self):
1350 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001351 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001352 """
1353 return X509()
1354
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001355 def test_type(self):
1356 """
Alex Gaynor31287502015-09-05 16:11:27 -04001357 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1358 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001359 """
1360 self.assertIdentical(X509, X509Type)
1361 self.assertConsistentType(X509, 'X509')
1362
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001363 def test_construction(self):
1364 """
Alex Gaynor31287502015-09-05 16:11:27 -04001365 :py:obj:`X509` takes no arguments and returns an instance of
1366 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001367 """
1368 certificate = X509()
1369 self.assertTrue(
1370 isinstance(certificate, X509Type),
1371 "%r is of type %r, should be %r" % (certificate,
1372 type(certificate),
1373 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001374 self.assertEqual(type(X509Type).__name__, 'type')
1375 self.assertEqual(type(certificate).__name__, 'X509')
1376 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001377 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001378
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001379 def test_get_version_wrong_args(self):
1380 """
Alex Gaynor31287502015-09-05 16:11:27 -04001381 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1382 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001383 """
1384 cert = X509()
1385 self.assertRaises(TypeError, cert.get_version, None)
1386
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001387 def test_set_version_wrong_args(self):
1388 """
Alex Gaynor31287502015-09-05 16:11:27 -04001389 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1390 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001391 """
1392 cert = X509()
1393 self.assertRaises(TypeError, cert.set_version)
1394 self.assertRaises(TypeError, cert.set_version, None)
1395 self.assertRaises(TypeError, cert.set_version, 1, None)
1396
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001397 def test_version(self):
1398 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001399 :py:obj:`X509.set_version` sets the certificate version number.
1400 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001401 """
1402 cert = X509()
1403 cert.set_version(1234)
1404 self.assertEquals(cert.get_version(), 1234)
1405
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001406 def test_get_serial_number_wrong_args(self):
1407 """
Alex Gaynor31287502015-09-05 16:11:27 -04001408 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1409 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001410 """
1411 cert = X509()
1412 self.assertRaises(TypeError, cert.get_serial_number, None)
1413
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001414 def test_serial_number(self):
1415 """
Alex Gaynor31287502015-09-05 16:11:27 -04001416 The serial number of an :py:obj:`X509Type` can be retrieved and
1417 modified with :py:obj:`X509Type.get_serial_number` and
1418 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001419 """
1420 certificate = X509()
1421 self.assertRaises(TypeError, certificate.set_serial_number)
1422 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1423 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1424 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1425 self.assertEqual(certificate.get_serial_number(), 0)
1426 certificate.set_serial_number(1)
1427 self.assertEqual(certificate.get_serial_number(), 1)
1428 certificate.set_serial_number(2 ** 32 + 1)
1429 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1430 certificate.set_serial_number(2 ** 64 + 1)
1431 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001432 certificate.set_serial_number(2 ** 128 + 1)
1433 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1434
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001435 def _setBoundTest(self, which):
1436 """
Alex Gaynor31287502015-09-05 16:11:27 -04001437 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1438 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1439 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001440 """
1441 certificate = X509()
1442 set = getattr(certificate, 'set_not' + which)
1443 get = getattr(certificate, 'get_not' + which)
1444
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001445 # Starts with no value.
1446 self.assertEqual(get(), None)
1447
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001448 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001449 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001450 set(when)
1451 self.assertEqual(get(), when)
1452
1453 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001454 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001455 set(when)
1456 self.assertEqual(get(), when)
1457
1458 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001459 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001460 set(when)
1461 self.assertEqual(get(), when)
1462
1463 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001464 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001465
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001466 # The wrong number of arguments results in a TypeError.
1467 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001468 with pytest.raises(TypeError):
1469 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001470 self.assertRaises(TypeError, get, b("foo bar"))
1471
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001472 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001473
1474 def test_set_notBefore(self):
1475 """
Alex Gaynor31287502015-09-05 16:11:27 -04001476 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1477 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1478 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001479 """
1480 self._setBoundTest("Before")
1481
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001482 def test_set_notAfter(self):
1483 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001484 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001485 GENERALIZEDTIME and sets the end of the certificate's validity period
1486 to it.
1487 """
1488 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001489
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001490 def test_get_notBefore(self):
1491 """
Alex Gaynor31287502015-09-05 16:11:27 -04001492 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1493 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001494 internally.
1495 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001496 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001497 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001498
Rick Dean38a05c82009-07-18 01:41:30 -05001499 def test_get_notAfter(self):
1500 """
Alex Gaynor31287502015-09-05 16:11:27 -04001501 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1502 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001503 internally.
1504 """
1505 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001506 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001507
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001508 def test_gmtime_adj_notBefore_wrong_args(self):
1509 """
Alex Gaynor31287502015-09-05 16:11:27 -04001510 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1511 called with the wrong number of arguments or a non-:py:obj:`int`
1512 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001513 """
1514 cert = X509()
1515 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1516 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1517 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1518
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001519 def test_gmtime_adj_notBefore(self):
1520 """
Alex Gaynor31287502015-09-05 16:11:27 -04001521 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1522 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001523 """
1524 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001525 not_before_min = (
1526 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1527 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001528 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001529 not_before = datetime.strptime(
1530 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1531 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001532 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1533 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001534
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001535 def test_gmtime_adj_notAfter_wrong_args(self):
1536 """
Alex Gaynor31287502015-09-05 16:11:27 -04001537 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1538 called with the wrong number of arguments or a non-:py:obj:`int`
1539 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001540 """
1541 cert = X509()
1542 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1543 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1544 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1545
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001546 def test_gmtime_adj_notAfter(self):
1547 """
Alex Gaynor31287502015-09-05 16:11:27 -04001548 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1549 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001550 """
1551 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001552 not_after_min = (
1553 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1554 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001555 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001556 not_after = datetime.strptime(
1557 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1558 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001559 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1560 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001561
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001562 def test_has_expired_wrong_args(self):
1563 """
Alex Gaynor31287502015-09-05 16:11:27 -04001564 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1565 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001566 """
1567 cert = X509()
1568 self.assertRaises(TypeError, cert.has_expired, None)
1569
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001570 def test_has_expired(self):
1571 """
Alex Gaynor31287502015-09-05 16:11:27 -04001572 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1573 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001574 """
1575 cert = X509()
1576 cert.gmtime_adj_notAfter(-1)
1577 self.assertTrue(cert.has_expired())
1578
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001579 def test_has_not_expired(self):
1580 """
Alex Gaynor31287502015-09-05 16:11:27 -04001581 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1582 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001583 """
1584 cert = X509()
1585 cert.gmtime_adj_notAfter(2)
1586 self.assertFalse(cert.has_expired())
1587
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001588 def test_root_has_not_expired(self):
1589 """
Alex Gaynor31287502015-09-05 16:11:27 -04001590 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1591 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001592 """
1593 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1594 self.assertFalse(cert.has_expired())
1595
Rick Dean38a05c82009-07-18 01:41:30 -05001596 def test_digest(self):
1597 """
Alex Gaynor31287502015-09-05 16:11:27 -04001598 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1599 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001600 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001601 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001602 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001603 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1604 # actually matters to the assertion (ie, another arbitrary, good
1605 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001606 # Digest verified with the command:
1607 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001608 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001609 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001610
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001611 def _extcert(self, pkey, extensions):
1612 cert = X509()
1613 cert.set_pubkey(pkey)
1614 cert.get_subject().commonName = "Unit Tests"
1615 cert.get_issuer().commonName = "Unit Tests"
1616 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1617 cert.set_notBefore(when)
1618 cert.set_notAfter(when)
1619
1620 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001621 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001622 return load_certificate(
1623 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1624
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001625 def test_extension_count(self):
1626 """
Alex Gaynor31287502015-09-05 16:11:27 -04001627 :py:obj:`X509.get_extension_count` returns the number of extensions
1628 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001629 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001630 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001631 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1632 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001633 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001634 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001635
1636 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001637 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001638 self.assertEqual(c.get_extension_count(), 0)
1639
1640 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001641 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001642 self.assertEqual(c.get_extension_count(), 1)
1643
1644 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001645 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001646 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001647
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001648 def test_get_extension(self):
1649 """
Alex Gaynor31287502015-09-05 16:11:27 -04001650 :py:obj:`X509.get_extension` takes an integer and returns an
1651 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001652 """
1653 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001654 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1655 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001656 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001657 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001658
1659 cert = self._extcert(pkey, [ca, key, subjectAltName])
1660
1661 ext = cert.get_extension(0)
1662 self.assertTrue(isinstance(ext, X509Extension))
1663 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001664 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001665
1666 ext = cert.get_extension(1)
1667 self.assertTrue(isinstance(ext, X509Extension))
1668 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001669 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001670
1671 ext = cert.get_extension(2)
1672 self.assertTrue(isinstance(ext, X509Extension))
1673 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001674 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001675
1676 self.assertRaises(IndexError, cert.get_extension, -1)
1677 self.assertRaises(IndexError, cert.get_extension, 4)
1678 self.assertRaises(TypeError, cert.get_extension, "hello")
1679
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001680 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001681 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001682 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001683 bytes and this value is reflected in the string representation of the
1684 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001685 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001686 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001687
1688 ext = cert.get_extension(3)
1689 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001690 self.assertEqual(
1691 b("DNS:altnull.python.org\x00example.com, "
1692 "email:null@python.org\x00user@example.org, "
1693 "URI:http://null.python.org\x00http://example.org, "
1694 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1695 b(str(ext)))
1696
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001697 def test_invalid_digest_algorithm(self):
1698 """
Alex Gaynor31287502015-09-05 16:11:27 -04001699 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1700 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001701 """
1702 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001703 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001704
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001705 def test_get_subject_wrong_args(self):
1706 """
Alex Gaynor31287502015-09-05 16:11:27 -04001707 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1708 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001709 """
1710 cert = X509()
1711 self.assertRaises(TypeError, cert.get_subject, None)
1712
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001713 def test_get_subject(self):
1714 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001715 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001716 """
1717 cert = load_certificate(FILETYPE_PEM, self.pemData)
1718 subj = cert.get_subject()
1719 self.assertTrue(isinstance(subj, X509Name))
1720 self.assertEquals(
1721 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001722 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1723 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001724
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001725 def test_set_subject_wrong_args(self):
1726 """
Alex Gaynor31287502015-09-05 16:11:27 -04001727 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1728 the wrong number of arguments or an argument not of type
1729 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001730 """
1731 cert = X509()
1732 self.assertRaises(TypeError, cert.set_subject)
1733 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001734 with pytest.raises(TypeError):
1735 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001736
1737 def test_set_subject(self):
1738 """
Alex Gaynor31287502015-09-05 16:11:27 -04001739 :py:obj:`X509.set_subject` changes the subject of the certificate to
1740 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001741 """
1742 cert = X509()
1743 name = cert.get_subject()
1744 name.C = 'AU'
1745 name.O = 'Unit Tests'
1746 cert.set_subject(name)
1747 self.assertEquals(
1748 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001749 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001750
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001751 def test_get_issuer_wrong_args(self):
1752 """
Alex Gaynor31287502015-09-05 16:11:27 -04001753 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1754 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001755 """
1756 cert = X509()
1757 self.assertRaises(TypeError, cert.get_issuer, None)
1758
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001759 def test_get_issuer(self):
1760 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001761 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001762 """
1763 cert = load_certificate(FILETYPE_PEM, self.pemData)
1764 subj = cert.get_issuer()
1765 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001766 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001767 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001768 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001769 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1770 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001771
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001772 def test_set_issuer_wrong_args(self):
1773 """
Alex Gaynor31287502015-09-05 16:11:27 -04001774 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1775 the wrong number of arguments or an argument not of type
1776 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001777 """
1778 cert = X509()
1779 self.assertRaises(TypeError, cert.set_issuer)
1780 self.assertRaises(TypeError, cert.set_issuer, None)
1781 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1782
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001783 def test_set_issuer(self):
1784 """
Alex Gaynor31287502015-09-05 16:11:27 -04001785 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1786 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001787 """
1788 cert = X509()
1789 name = cert.get_issuer()
1790 name.C = 'AU'
1791 name.O = 'Unit Tests'
1792 cert.set_issuer(name)
1793 self.assertEquals(
1794 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001795 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001796
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001797 def test_get_pubkey_uninitialized(self):
1798 """
Alex Gaynor31287502015-09-05 16:11:27 -04001799 When called on a certificate with no public key,
1800 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001801 """
1802 cert = X509()
1803 self.assertRaises(Error, cert.get_pubkey)
1804
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001805 def test_subject_name_hash_wrong_args(self):
1806 """
Alex Gaynor31287502015-09-05 16:11:27 -04001807 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1808 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001809 """
1810 cert = X509()
1811 self.assertRaises(TypeError, cert.subject_name_hash, None)
1812
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001813 def test_subject_name_hash(self):
1814 """
Alex Gaynor31287502015-09-05 16:11:27 -04001815 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1816 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001817 """
1818 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001819 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001820 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001821 [3350047874, # OpenSSL 0.9.8, MD5
1822 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001823 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001824
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001825 def test_get_signature_algorithm(self):
1826 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001827 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001828 the algorithm used to sign the certificate.
1829 """
1830 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001831 self.assertEqual(
1832 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001833
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001834 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001835 """
Alex Gaynor31287502015-09-05 16:11:27 -04001836 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1837 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001838 """
1839 # This certificate has been modified to indicate a bogus OID in the
1840 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001841 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001842-----BEGIN CERTIFICATE-----
1843MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1844EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1845cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1846MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1847EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1848CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1849AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1850+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1851hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1852BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1853FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1854dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1855aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1856MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1857jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1858PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1859tgI5
1860-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001861""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001862 cert = load_certificate(FILETYPE_PEM, certPEM)
1863 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001864
1865
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001866class X509StoreTests(TestCase):
1867 """
1868 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1869 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001870
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001871 def test_type(self):
1872 """
1873 :py:obj:`X509StoreType` is a type object.
1874 """
1875 self.assertIdentical(X509Store, X509StoreType)
1876 self.assertConsistentType(X509Store, 'X509Store')
1877
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001878 def test_add_cert_wrong_args(self):
1879 store = X509Store()
1880 self.assertRaises(TypeError, store.add_cert)
1881 self.assertRaises(TypeError, store.add_cert, object())
1882 self.assertRaises(TypeError, store.add_cert, X509(), object())
1883
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001884 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001885 """
1886 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1887 certificate store.
1888 """
1889 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001890 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001891 store.add_cert(cert)
1892
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001893 def test_add_cert_rejects_duplicate(self):
1894 """
Alex Gaynor31287502015-09-05 16:11:27 -04001895 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1896 an attempt is made to add the same certificate to the store more than
1897 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001898 """
1899 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1900 store = X509Store()
1901 store.add_cert(cert)
1902 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001903
1904
Rick Dean623ee362009-07-17 12:22:16 -05001905class PKCS12Tests(TestCase):
1906 """
Alex Gaynor31287502015-09-05 16:11:27 -04001907 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1908 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001909 """
1910 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1911
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001912 def test_type(self):
1913 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001914 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001915 """
1916 self.assertIdentical(PKCS12, PKCS12Type)
1917 self.assertConsistentType(PKCS12, 'PKCS12')
1918
Rick Deanf94096c2009-07-18 14:23:06 -05001919 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001920 """
Alex Gaynor31287502015-09-05 16:11:27 -04001921 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1922 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001923 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001924 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001925 self.assertEqual(None, p12.get_certificate())
1926 self.assertEqual(None, p12.get_privatekey())
1927 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001928 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001929
1930 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001931 """
Alex Gaynor31287502015-09-05 16:11:27 -04001932 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1933 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1934 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1935 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001936 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001937 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001938 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001939 self.assertRaises(TypeError, p12.set_certificate, PKey())
1940 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001941 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001942 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1943 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001944 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1945 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1946 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001947 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001948 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1949 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001950
1951 def test_key_only(self):
1952 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001953 A :py:obj:`PKCS12` with only a private key can be exported using
1954 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001955 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001956 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001957 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001958 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001959 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05001960 self.assertEqual(None, p12.get_certificate())
1961 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001962 try:
1963 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1964 except Error:
1965 # Some versions of OpenSSL will throw an exception
1966 # for this nearly useless PKCS12 we tried to generate:
1967 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1968 return
Rick Dean623ee362009-07-17 12:22:16 -05001969 p12 = load_pkcs12(dumped_p12, passwd)
1970 self.assertEqual(None, p12.get_ca_certificates())
1971 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001972
1973 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1974 # future this will be improved.
1975 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05001976
1977 def test_cert_only(self):
1978 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001979 A :py:obj:`PKCS12` with only a certificate can be exported using
1980 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001981 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001982 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001983 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001984 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001985 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05001986 self.assertEqual(cert, p12.get_certificate())
1987 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001988 try:
1989 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1990 except Error:
1991 # Some versions of OpenSSL will throw an exception
1992 # for this nearly useless PKCS12 we tried to generate:
1993 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1994 return
Rick Dean623ee362009-07-17 12:22:16 -05001995 p12 = load_pkcs12(dumped_p12, passwd)
1996 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001997
1998 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
1999 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
2000
2001 # Oh ho. It puts the certificate into the ca certificates list, in
2002 # fact. Totally bogus, I would think. Nevertheless, let's exploit
2003 # that to check to see if it reconstructed the certificate we expected
2004 # it to. At some point, hopefully this will change so that
2005 # p12.get_certificate() is actually what returns the loaded
2006 # certificate.
2007 self.assertEqual(
2008 cleartextCertificatePEM,
2009 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05002010
Alex Gaynor31287502015-09-05 16:11:27 -04002011 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
2012 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05002013 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002014 Generate a PKCS12 object with components from PEM. Verify that the set
2015 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05002016 """
Rick Deanf94096c2009-07-18 14:23:06 -05002017 p12 = PKCS12()
2018 if cert_pem:
2019 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
2020 self.assertEqual(ret, None)
2021 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002022 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05002023 self.assertEqual(ret, None)
2024 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04002025 ret = p12.set_ca_certificates(
2026 (load_certificate(FILETYPE_PEM, ca_pem),)
2027 )
Rick Deanf94096c2009-07-18 14:23:06 -05002028 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002029 if friendly_name:
2030 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05002031 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05002032 return p12
2033
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002034 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002035 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05002036 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002037 Use openssl program to confirm three components are recoverable from a
2038 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05002039 """
2040 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002041 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002042 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
2043 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002044 self.assertEqual(recovered_key[-len(key):], key)
2045 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002046 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002047 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
2048 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002049 self.assertEqual(recovered_cert[-len(cert):], cert)
2050 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002051 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002052 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
2053 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002054 self.assertEqual(recovered_cert[-len(ca):], ca)
2055
Stephen Holsapple38482622014-04-05 20:29:34 -07002056 def verify_pkcs12_container(self, p12):
2057 """
2058 Verify that the PKCS#12 container contains the correct client
2059 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002060
2061 :param p12: The PKCS12 instance to verify.
2062 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002063 """
2064 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2065 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002066 self.assertEqual(
2067 (client_cert_pem, client_key_pem, None),
2068 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002069
Rick Deanf94096c2009-07-18 14:23:06 -05002070 def test_load_pkcs12(self):
2071 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002072 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002073 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002074 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002075 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002076 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002077 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002078 pem,
2079 b"pkcs12",
2080 b"-export",
2081 b"-clcerts",
2082 b"-passout",
2083 b"pass:" + passwd
2084 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002085 p12 = load_pkcs12(p12_str, passphrase=passwd)
2086 self.verify_pkcs12_container(p12)
2087
Abraham Martinc5484ba2015-03-25 15:33:05 +00002088 def test_load_pkcs12_text_passphrase(self):
2089 """
2090 A PKCS12 string generated using the openssl command line can be loaded
2091 with :py:obj:`load_pkcs12` and its components extracted and examined.
2092 Using text as passphrase instead of bytes. DeprecationWarning expected.
2093 """
2094 pem = client_key_pem + client_cert_pem
2095 passwd = b"whatever"
2096 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2097 b"-passout", b"pass:" + passwd)
2098 with catch_warnings(record=True) as w:
2099 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002100 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002101
2102 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002103 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002104 WARNING_TYPE_EXPECTED
2105 ),
2106 str(w[-1].message)
2107 )
2108 self.assertIs(w[-1].category, DeprecationWarning)
2109
Abraham Martinc5484ba2015-03-25 15:33:05 +00002110 self.verify_pkcs12_container(p12)
2111
Stephen Holsapple38482622014-04-05 20:29:34 -07002112 def test_load_pkcs12_no_passphrase(self):
2113 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002114 A PKCS12 string generated using openssl command line can be loaded with
2115 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2116 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002117 """
2118 pem = client_key_pem + client_cert_pem
2119 p12_str = _runopenssl(
2120 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2121 p12 = load_pkcs12(p12_str)
2122 self.verify_pkcs12_container(p12)
2123
Stephen Holsapple38482622014-04-05 20:29:34 -07002124 def _dump_and_load(self, dump_passphrase, load_passphrase):
2125 """
2126 A helper method to dump and load a PKCS12 object.
2127 """
2128 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2129 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2130 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2131
Stephen Holsapple38482622014-04-05 20:29:34 -07002132 def test_load_pkcs12_null_passphrase_load_empty(self):
2133 """
2134 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002135 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002136 extracted and examined.
2137 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002138 self.verify_pkcs12_container(
2139 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002140
Stephen Holsapple38482622014-04-05 20:29:34 -07002141 def test_load_pkcs12_null_passphrase_load_null(self):
2142 """
2143 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002144 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002145 extracted and examined.
2146 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002147 self.verify_pkcs12_container(
2148 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002149
Stephen Holsapple38482622014-04-05 20:29:34 -07002150 def test_load_pkcs12_empty_passphrase_load_empty(self):
2151 """
2152 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002153 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002154 extracted and examined.
2155 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002156 self.verify_pkcs12_container(
2157 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002158
Stephen Holsapple38482622014-04-05 20:29:34 -07002159 def test_load_pkcs12_empty_passphrase_load_null(self):
2160 """
2161 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002162 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002163 extracted and examined.
2164 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002165 self.verify_pkcs12_container(
2166 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002167
Rick Deanee568302009-07-24 09:56:29 -05002168 def test_load_pkcs12_garbage(self):
2169 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002170 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2171 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002172 """
2173 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002174 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002175 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2176 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002177
Rick Deanf94096c2009-07-18 14:23:06 -05002178 def test_replace(self):
2179 """
Alex Gaynor31287502015-09-05 16:11:27 -04002180 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2181 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002182 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002183 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002184 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2185 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2186 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002187 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002188 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002189 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002190 self.assertEqual(1, len(p12.get_ca_certificates()))
2191 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002192 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002193 self.assertEqual(2, len(p12.get_ca_certificates()))
2194 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2195 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2196
Rick Deanf94096c2009-07-18 14:23:06 -05002197 def test_friendly_name(self):
2198 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002199 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002200 :py:obj:`PKCS12.get_friendlyname` and
2201 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2202 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002203 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002204 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002205 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002206 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002207 p12.set_friendlyname(friendly_name)
2208 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002209 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002210 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002211 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002212 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002213 # We would use the openssl program to confirm the friendly
2214 # name, but it is not possible. The pkcs12 command
2215 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002216 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002217 self.check_recovery(
2218 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2219 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002220
Rick Deanf94096c2009-07-18 14:23:06 -05002221 def test_various_empty_passphrases(self):
2222 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002223 Test that missing, None, and '' passphrases are identical for PKCS12
2224 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002225 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002226 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002227 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002228 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2229 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2230 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2231 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2232 self.check_recovery(
2233 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2234 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002235
Rick Deanf94096c2009-07-18 14:23:06 -05002236 def test_removing_ca_cert(self):
2237 """
Alex Gaynor31287502015-09-05 16:11:27 -04002238 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2239 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002240 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002241 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2242 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002243 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002244
Rick Deanf94096c2009-07-18 14:23:06 -05002245 def test_export_without_mac(self):
2246 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002247 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002248 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002249 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002250 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002251 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002252 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002253 self.check_recovery(
2254 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002255 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002256
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002257 def test_load_without_mac(self):
2258 """
2259 Loading a PKCS12 without a MAC does something other than crash.
2260 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002261 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002262 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2263 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002264 try:
2265 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2266 # The person who generated this PCKS12 should be flogged,
2267 # or better yet we should have a means to determine
2268 # whether a PCKS12 had a MAC that was verified.
2269 # Anyway, libopenssl chooses to allow it, so the
2270 # pyopenssl binding does as well.
2271 self.assertTrue(isinstance(recovered_p12, PKCS12))
2272 except Error:
2273 # Failing here with an exception is preferred as some openssl
2274 # versions do.
2275 pass
Rick Dean623ee362009-07-17 12:22:16 -05002276
Rick Dean25bcc1f2009-07-20 11:53:13 -05002277 def test_zero_len_list_for_ca(self):
2278 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002279 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002280 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002281 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002282 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002283 p12.set_ca_certificates([])
2284 self.assertEqual((), p12.get_ca_certificates())
2285 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2286 self.check_recovery(
2287 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2288 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002289
Rick Deanf94096c2009-07-18 14:23:06 -05002290 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002291 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002292 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002293 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002294 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002295 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002296 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002297 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002298
Abraham Martinc5484ba2015-03-25 15:33:05 +00002299 def test_export_without_bytes(self):
2300 """
2301 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2302 """
2303 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2304
2305 with catch_warnings(record=True) as w:
2306 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002307 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002308 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002309 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002310 WARNING_TYPE_EXPECTED
2311 ),
2312 str(w[-1].message)
2313 )
2314 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002315 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002316 dumped_p12,
2317 key=server_key_pem,
2318 cert=server_cert_pem,
2319 passwd=b"randomtext"
2320 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002321
Rick Deanf94096c2009-07-18 14:23:06 -05002322 def test_key_cert_mismatch(self):
2323 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002324 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002325 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002326 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002327 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2328 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002329
2330
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002331# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002332_cmdLineQuoteRe = re.compile(br'(\\*)"')
2333_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002334
2335
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002336def cmdLineQuote(s):
2337 """
2338 Internal method for quoting a single command-line argument.
2339
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002340 See http://www.perlmonks.org/?node_id=764004
2341
Jonathan Ballet648875f2011-07-16 14:14:58 +09002342 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002343 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002344 cmd.exe-style quoting
2345
Jonathan Ballet648875f2011-07-16 14:14:58 +09002346 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002347 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002348 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002349 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2350 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002351
2352
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002353def quoteArguments(arguments):
2354 """
2355 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002356 a similar API. This allows the list passed to
2357 :py:obj:`reactor.spawnProcess` to match the child process's
2358 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002359
Jonathan Ballet648875f2011-07-16 14:14:58 +09002360 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002361 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002362
Jonathan Ballet648875f2011-07-16 14:14:58 +09002363 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002364 :return: A space-delimited string containing quoted versions of
2365 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002366 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002367 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002368
2369
Rick Dean4c9ad612009-07-17 15:05:22 -05002370def _runopenssl(pem, *args):
2371 """
2372 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002373 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002374 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002375 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002376 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002377 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2378 for arg in args
2379 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002380 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002381 command = b"openssl " + quoteArguments(args)
2382 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002383 proc.stdin.write(pem)
2384 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002385 output = proc.stdout.read()
2386 proc.stdout.close()
2387 proc.wait()
2388 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002389
2390
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002391class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002392 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002393 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002394 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002395
2396 def test_load_privatekey_invalid_format(self):
2397 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002398 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2399 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002400 """
2401 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2402
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002403 def test_load_privatekey_invalid_passphrase_type(self):
2404 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002405 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2406 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002407 """
2408 self.assertRaises(
2409 TypeError,
2410 load_privatekey,
2411 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2412
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002413 def test_load_privatekey_wrong_args(self):
2414 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002415 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2416 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002417 """
2418 self.assertRaises(TypeError, load_privatekey)
2419
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002420 def test_load_privatekey_wrongPassphrase(self):
2421 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002422 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2423 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002424 """
2425 self.assertRaises(
2426 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002427 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002428
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002429 def test_load_privatekey_passphraseWrongType(self):
2430 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002431 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2432 a passphrase with a private key encoded in a format, that doesn't
2433 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002434 """
2435 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2436 blob = dump_privatekey(FILETYPE_ASN1, key)
2437 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002438 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002439
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002440 def test_load_privatekey_passphrase(self):
2441 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002442 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2443 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002444 """
2445 key = load_privatekey(
2446 FILETYPE_PEM, encryptedPrivateKeyPEM,
2447 encryptedPrivateKeyPEMPassphrase)
2448 self.assertTrue(isinstance(key, PKeyType))
2449
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002450 def test_load_privatekey_passphrase_exception(self):
2451 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002452 If the passphrase callback raises an exception, that exception is
2453 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002454 """
2455 def cb(ignored):
2456 raise ArithmeticError
2457
Alex Gaynor791212d2015-09-05 15:46:08 -04002458 with pytest.raises(ArithmeticError):
2459 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002460
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002461 def test_load_privatekey_wrongPassphraseCallback(self):
2462 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002463 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2464 is passed an encrypted PEM and a passphrase callback which returns an
2465 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002466 """
2467 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002468
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002469 def cb(*a):
2470 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002471 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002472 self.assertRaises(
2473 Error,
2474 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2475 self.assertTrue(called)
2476
2477 def test_load_privatekey_passphraseCallback(self):
2478 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002479 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2480 encrypted PEM string if given a passphrase callback which returns the
2481 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002482 """
2483 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002484
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002485 def cb(writing):
2486 called.append(writing)
2487 return encryptedPrivateKeyPEMPassphrase
2488 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2489 self.assertTrue(isinstance(key, PKeyType))
2490 self.assertEqual(called, [False])
2491
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002492 def test_load_privatekey_passphrase_wrong_return_type(self):
2493 """
2494 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2495 callback returns something other than a byte string.
2496 """
2497 self.assertRaises(
2498 ValueError,
2499 load_privatekey,
2500 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2501
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002502 def test_dump_privatekey_wrong_args(self):
2503 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002504 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2505 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002506 """
2507 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002508 # If cipher name is given, password is required.
2509 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002510 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002511
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002512 def test_dump_privatekey_unknown_cipher(self):
2513 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002514 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2515 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002516 """
2517 key = PKey()
2518 key.generate_key(TYPE_RSA, 512)
2519 self.assertRaises(
2520 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002521 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002522
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002523 def test_dump_privatekey_invalid_passphrase_type(self):
2524 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002525 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2526 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002527 """
2528 key = PKey()
2529 key.generate_key(TYPE_RSA, 512)
2530 self.assertRaises(
2531 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002532 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002533
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002534 def test_dump_privatekey_invalid_filetype(self):
2535 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002536 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2537 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002538 """
2539 key = PKey()
2540 key.generate_key(TYPE_RSA, 512)
2541 self.assertRaises(ValueError, dump_privatekey, 100, key)
2542
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002543 def test_load_privatekey_passphraseCallbackLength(self):
2544 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002545 :py:obj:`crypto.load_privatekey` should raise an error when the
2546 passphrase provided by the callback is too long, not silently truncate
2547 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002548 """
2549 def cb(ignored):
2550 return "a" * 1025
2551
Alex Gaynor791212d2015-09-05 15:46:08 -04002552 with pytest.raises(ValueError):
2553 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002554
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002555 def test_dump_privatekey_passphrase(self):
2556 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002557 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2558 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002559 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002560 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002561 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002562 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2563 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002564 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2565 self.assertTrue(isinstance(loadedKey, PKeyType))
2566 self.assertEqual(loadedKey.type(), key.type())
2567 self.assertEqual(loadedKey.bits(), key.bits())
2568
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002569 def test_dump_privatekey_passphraseWrongType(self):
2570 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002571 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2572 a passphrase with a private key encoded in a format, that doesn't
2573 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002574 """
2575 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002576 with pytest.raises(ValueError):
2577 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002578
Rick Dean5b7b6372009-04-01 11:34:06 -05002579 def test_dump_certificate(self):
2580 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002581 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002582 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002583 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002584 cert = load_certificate(FILETYPE_PEM, pemData)
2585 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2586 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2587 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002588 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002589 self.assertEqual(dumped_der, good_der)
2590 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2591 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2592 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2593 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002594 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002595 self.assertEqual(dumped_text, good_text)
2596
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002597 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002598 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002599 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002600 """
2601 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002602 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002603 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2604 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002605
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002606 def test_dump_privatekey_asn1(self):
2607 """
2608 :py:obj:`dump_privatekey` writes a DER
2609 """
2610 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2611 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2612
Rick Dean5b7b6372009-04-01 11:34:06 -05002613 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002614 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002615 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002616 self.assertEqual(dumped_der, good_der)
2617 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2618 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2619 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002620
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002621 def test_dump_privatekey_text(self):
2622 """
2623 :py:obj:`dump_privatekey` writes a text
2624 """
2625 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2626 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2627
Rick Dean5b7b6372009-04-01 11:34:06 -05002628 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002629 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002630 self.assertEqual(dumped_text, good_text)
2631
Cory Benfield6492f7c2015-10-27 16:57:58 +09002632 def test_dump_publickey_pem(self):
2633 """
Cory Benfield11c10192015-10-27 17:23:03 +09002634 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002635 """
2636 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2637 dumped_pem = dump_publickey(FILETYPE_PEM, key)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002638 assert dumped_pem == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002639
2640 def test_dump_publickey_asn1(self):
2641 """
Cory Benfield11c10192015-10-27 17:23:03 +09002642 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002643 """
2644 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2645 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2646 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2647 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
Cory Benfieldd86f1d82015-10-27 17:25:17 +09002648 assert dumped_pem2 == cleartextPublicKeyPEM
Cory Benfield6492f7c2015-10-27 16:57:58 +09002649
Cory Benfielde02c7d82015-10-27 17:34:49 +09002650 def test_dump_publickey_invalid_type(self):
2651 """
2652 dump_publickey doesn't support FILETYPE_TEXT.
2653 """
2654 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2655
2656 with pytest.raises(ValueError):
2657 dump_publickey(FILETYPE_TEXT, key)
2658
2659 def test_load_publickey_invalid_type(self):
2660 """
2661 load_publickey doesn't support FILETYPE_TEXT.
2662 """
2663 with pytest.raises(ValueError):
2664 load_publickey(FILETYPE_TEXT, cleartextPublicKeyPEM)
2665
2666 def test_load_publickey_invalid_key_format(self):
2667 """
2668 load_publickey explodes on incorrect keys.
2669 """
2670 with pytest.raises(Error):
2671 load_publickey(FILETYPE_ASN1, cleartextPublicKeyPEM)
2672
2673 def test_load_publickey_tolerates_unicode_strings(self):
2674 """
2675 load_publickey works with text strings, not just bytes.
2676 """
2677 serialized = cleartextPublicKeyPEM.decode('ascii')
2678 key = load_publickey(FILETYPE_PEM, serialized)
2679 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2680 assert dumped_pem == cleartextPublicKeyPEM
2681
Rick Dean5b7b6372009-04-01 11:34:06 -05002682 def test_dump_certificate_request(self):
2683 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002684 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002685 """
Alex Gaynor31287502015-09-05 16:11:27 -04002686 req = load_certificate_request(
2687 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002688 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2689 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2690 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002691 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002692 self.assertEqual(dumped_der, good_der)
2693 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2694 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2695 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2696 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002697 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002698 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002699 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002700
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002701 def test_dump_privatekey_passphraseCallback(self):
2702 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002703 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2704 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002705 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002706 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002707 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002708
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002709 def cb(writing):
2710 called.append(writing)
2711 return passphrase
2712 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002713 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2714 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002715 self.assertEqual(called, [True])
2716 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2717 self.assertTrue(isinstance(loadedKey, PKeyType))
2718 self.assertEqual(loadedKey.type(), key.type())
2719 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002720
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002721 def test_dump_privatekey_passphrase_exception(self):
2722 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002723 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002724 by the passphrase callback.
2725 """
2726 def cb(ignored):
2727 raise ArithmeticError
2728
2729 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002730 with pytest.raises(ArithmeticError):
2731 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002732
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002733 def test_dump_privatekey_passphraseCallbackLength(self):
2734 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002735 :py:obj:`crypto.dump_privatekey` should raise an error when the
2736 passphrase provided by the callback is too long, not silently truncate
2737 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002738 """
2739 def cb(ignored):
2740 return "a" * 1025
2741
2742 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002743 with pytest.raises(ValueError):
2744 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002745
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002746 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002747 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002748 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2749 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002750 """
2751 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2752 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2753
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002754 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002755 """
2756 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2757 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2758 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002759 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2760 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2761
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002762 def test_load_pkcs7_data_invalid(self):
2763 """
2764 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2765 :py:obj:`Error` is raised.
2766 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002767 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002768
2769
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002770class LoadCertificateTests(TestCase):
2771 """
2772 Tests for :py:obj:`load_certificate_request`.
2773 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002774
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002775 def test_badFileType(self):
2776 """
2777 If the file type passed to :py:obj:`load_certificate_request` is
2778 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2779 :py:class:`ValueError` is raised.
2780 """
2781 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2782
2783
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002784class PKCS7Tests(TestCase):
2785 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002786 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002787 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002788
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002789 def test_type(self):
2790 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002791 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002792 """
2793 self.assertTrue(isinstance(PKCS7Type, type))
2794 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2795
2796 # XXX This doesn't currently work.
2797 # self.assertIdentical(PKCS7, PKCS7Type)
2798
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002799 # XXX Opposite results for all these following methods
2800
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002801 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002802 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002803 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2804 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002805 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002806 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2807 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2808
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002809 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002810 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002811 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2812 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002813 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002814 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2815 self.assertTrue(pkcs7.type_is_signed())
2816
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002817 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002818 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002819 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2820 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002821 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002822 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2823 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2824
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002825 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002826 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002827 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2828 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002829 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002830 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2831 self.assertFalse(pkcs7.type_is_enveloped())
2832
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002833 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002834 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002835 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2836 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002837 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002838 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2839 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2840
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002841 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002842 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002843 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2844 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002845 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002846 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2847 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2848
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002849 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002850 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002851 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2852 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002853 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002854 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2855 self.assertFalse(pkcs7.type_is_data())
2856
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002857 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002858 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002859 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2860 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002861 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002862 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2863 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2864
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002865 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002866 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002867 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2868 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002869 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002870 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2871 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2872
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002873 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002874 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002875 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2876 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002877 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002878 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002879 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002880
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002881 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002882 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002883 If an attribute other than one of the methods tested here is accessed
2884 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2885 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002886 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002887 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2888 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2889
2890
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002891class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002892 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002893 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002894 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002895
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002896 def signable(self):
2897 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002898 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002899 """
2900 return NetscapeSPKI()
2901
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002902 def test_type(self):
2903 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002904 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2905 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002906 """
2907 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2908 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2909
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002910 def test_construction(self):
2911 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002912 :py:obj:`NetscapeSPKI` returns an instance of
2913 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002914 """
2915 nspki = NetscapeSPKI()
2916 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2917
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002918 def test_invalid_attribute(self):
2919 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002920 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2921 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002922 """
2923 nspki = NetscapeSPKI()
2924 self.assertRaises(AttributeError, lambda: nspki.foo)
2925
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002926 def test_b64_encode(self):
2927 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002928 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2929 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002930 """
2931 nspki = NetscapeSPKI()
2932 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002933 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002934
2935
Rick Dean536ba022009-07-24 23:57:27 -05002936class RevokedTests(TestCase):
2937 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002938 Tests for :py:obj:`OpenSSL.crypto.Revoked`
Rick Dean536ba022009-07-24 23:57:27 -05002939 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002940
Rick Dean536ba022009-07-24 23:57:27 -05002941 def test_construction(self):
2942 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002943 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002944 that it is empty.
2945 """
2946 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002947 self.assertTrue(isinstance(revoked, Revoked))
2948 self.assertEquals(type(revoked), Revoked)
2949 self.assertEquals(revoked.get_serial(), b('00'))
2950 self.assertEquals(revoked.get_rev_date(), None)
2951 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05002952
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002953 def test_construction_wrong_args(self):
2954 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002955 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
2956 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002957 """
2958 self.assertRaises(TypeError, Revoked, None)
2959 self.assertRaises(TypeError, Revoked, 1)
2960 self.assertRaises(TypeError, Revoked, "foo")
2961
Rick Dean536ba022009-07-24 23:57:27 -05002962 def test_serial(self):
2963 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002964 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002965 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002966 with grace.
2967 """
2968 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002969 ret = revoked.set_serial(b('10b'))
2970 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002971 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002972 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05002973
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002974 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05002975 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002976 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05002977
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002978 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05002979 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002980 self.assertRaises(TypeError, revoked.get_serial, 1)
2981 self.assertRaises(TypeError, revoked.get_serial, None)
2982 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05002983
Rick Dean536ba022009-07-24 23:57:27 -05002984 def test_date(self):
2985 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002986 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002987 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002988 with grace.
2989 """
2990 revoked = Revoked()
2991 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002992 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05002993
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002994 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002995 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002996 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002997 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002998 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05002999
Rick Dean6385faf2009-07-26 00:07:47 -05003000 def test_reason(self):
3001 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003002 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09003003 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05003004 as "set". Likewise, each reason of all_reasons() must work.
3005 """
3006 revoked = Revoked()
3007 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003008 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05003009 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003010 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05003011 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04003012 self.assertEquals(
3013 reason.lower().replace(b(' '), b('')),
3014 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003015 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05003016
3017 revoked.set_reason(None)
3018 self.assertEqual(revoked.get_reason(), None)
3019
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003020 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05003021 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003022 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003023 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09003024 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05003025 """
3026 revoked = Revoked()
3027 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04003028 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05003029
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003030 def test_get_reason_wrong_arguments(self):
3031 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003032 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
3033 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05003034 """
3035 revoked = Revoked()
3036 self.assertRaises(TypeError, revoked.get_reason, None)
3037 self.assertRaises(TypeError, revoked.get_reason, 1)
3038 self.assertRaises(TypeError, revoked.get_reason, "foo")
3039
3040
Rick Dean536ba022009-07-24 23:57:27 -05003041class CRLTests(TestCase):
3042 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003043 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05003044 """
3045 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
3046 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
3047
3048 def test_construction(self):
3049 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003050 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05003051 that it is empty
3052 """
3053 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04003054 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05003055 self.assertEqual(crl.get_revoked(), None)
3056
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003057 def test_construction_wrong_args(self):
3058 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003059 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
3060 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05003061 """
3062 self.assertRaises(TypeError, CRL, 1)
3063 self.assertRaises(TypeError, CRL, "")
3064 self.assertRaises(TypeError, CRL, None)
3065
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003066 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05003067 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003068 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05003069 """
3070 crl = CRL()
3071 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003072 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003073 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003074 revoked.set_serial(b('3ab'))
3075 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003076 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003077 return crl
Rick Dean536ba022009-07-24 23:57:27 -05003078
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003079 def test_export_pem(self):
3080 """
3081 If not passed a format, ``CRL.export`` returns a "PEM" format string
3082 representing a serial number, a revoked reason, and certificate issuer
3083 information.
3084 """
3085 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003086 # PEM format
3087 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003088 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003089
3090 # These magic values are based on the way the CRL above was constructed
3091 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003092 text.index(b('Serial Number: 03AB'))
3093 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003094 text.index(
3095 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3096 )
3097
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003098 def test_export_der(self):
3099 """
3100 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3101 "DER" format string representing a serial number, a revoked reason, and
3102 certificate issuer information.
3103 """
3104 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003105
3106 # DER format
3107 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003108 text = _runopenssl(
3109 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3110 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003111 text.index(b('Serial Number: 03AB'))
3112 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003113 text.index(
3114 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3115 )
3116
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003117 def test_export_text(self):
3118 """
3119 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3120 text format string like the one produced by the openssl command line
3121 tool.
3122 """
3123 crl = self._get_crl()
3124
3125 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3126 text = _runopenssl(
3127 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3128 )
Rick Dean536ba022009-07-24 23:57:27 -05003129
3130 # text format
3131 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3132 self.assertEqual(text, dumped_text)
3133
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003134 def test_export_custom_digest(self):
3135 """
3136 If passed the name of a digest function, ``CRL.export`` uses a
3137 signature algorithm based on that digest function.
3138 """
3139 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003140 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003141 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3142 text.index(b('Signature Algorithm: sha1'))
3143
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003144 def test_export_md5_digest(self):
3145 """
3146 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3147 not emit a deprecation warning.
3148 """
3149 crl = self._get_crl()
3150 with catch_warnings(record=True) as catcher:
3151 simplefilter("always")
3152 self.assertEqual(0, len(catcher))
3153 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3154 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3155 text.index(b('Signature Algorithm: md5'))
3156
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003157 def test_export_default_digest(self):
3158 """
3159 If not passed the name of a digest function, ``CRL.export`` uses a
3160 signature algorithm based on MD5 and emits a deprecation warning.
3161 """
3162 crl = self._get_crl()
3163 with catch_warnings(record=True) as catcher:
3164 simplefilter("always")
3165 dumped_crl = crl.export(self.cert, self.pkey)
3166 self.assertEqual(
3167 "The default message digest (md5) is deprecated. "
3168 "Pass the name of a message digest explicitly.",
3169 str(catcher[0].message),
3170 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003171 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3172 text.index(b('Signature Algorithm: md5'))
3173
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003174 def test_export_invalid(self):
3175 """
3176 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003177 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003178 """
3179 crl = CRL()
3180 self.assertRaises(Error, crl.export, X509(), PKey())
3181
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003182 def test_add_revoked_keyword(self):
3183 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003184 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003185 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003186 """
3187 crl = CRL()
3188 revoked = Revoked()
3189 crl.add_revoked(revoked=revoked)
3190 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3191
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003192 def test_export_wrong_args(self):
3193 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003194 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003195 four arguments, or with arguments other than the certificate,
3196 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003197 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003198 """
3199 crl = CRL()
3200 self.assertRaises(TypeError, crl.export)
3201 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003202 with pytest.raises(TypeError):
3203 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3204 with pytest.raises(TypeError):
3205 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3206 with pytest.raises(TypeError):
3207 crl.export(self.cert, None, FILETYPE_PEM, 10)
3208 with pytest.raises(TypeError):
3209 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003210 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3211
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003212 def test_export_unknown_filetype(self):
3213 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003214 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003215 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3216 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003217 """
3218 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003219 with pytest.raises(ValueError):
3220 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003221
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003222 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003223 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003224 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003225 in a :py:obj:`ValueError` being raised.
3226 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003227 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003228 self.assertRaises(
3229 ValueError,
3230 crl.export,
3231 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3232 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003233
Rick Dean536ba022009-07-24 23:57:27 -05003234 def test_get_revoked(self):
3235 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003236 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003237 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3238 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003239 """
3240 crl = CRL()
3241
3242 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003243 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003244 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003245 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003246 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003247 revoked.set_serial(b('100'))
3248 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003249 crl.add_revoked(revoked)
3250
3251 revs = crl.get_revoked()
3252 self.assertEqual(len(revs), 2)
3253 self.assertEqual(type(revs[0]), Revoked)
3254 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003255 self.assertEqual(revs[0].get_serial(), b('03AB'))
3256 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003257 self.assertEqual(revs[0].get_rev_date(), now)
3258 self.assertEqual(revs[1].get_rev_date(), now)
3259
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003260 def test_get_revoked_wrong_args(self):
3261 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003262 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3263 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003264 """
3265 crl = CRL()
3266 self.assertRaises(TypeError, crl.get_revoked, None)
3267 self.assertRaises(TypeError, crl.get_revoked, 1)
3268 self.assertRaises(TypeError, crl.get_revoked, "")
3269 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3270
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003271 def test_add_revoked_wrong_args(self):
3272 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003273 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3274 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003275 """
3276 crl = CRL()
3277 self.assertRaises(TypeError, crl.add_revoked)
3278 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3279 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3280
Rick Dean536ba022009-07-24 23:57:27 -05003281 def test_load_crl(self):
3282 """
3283 Load a known CRL and inspect its revocations. Both
3284 PEM and DER formats are loaded.
3285 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003286 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003287 revs = crl.get_revoked()
3288 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003289 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003290 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003291 self.assertEqual(revs[1].get_serial(), b('0100'))
3292 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003293
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003294 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003295 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003296 revs = crl.get_revoked()
3297 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003298 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003299 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003300 self.assertEqual(revs[1].get_serial(), b('0100'))
3301 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003302
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003303 def test_load_crl_wrong_args(self):
3304 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003305 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3306 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003307 """
3308 self.assertRaises(TypeError, load_crl)
3309 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3310 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3311
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003312 def test_load_crl_bad_filetype(self):
3313 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003314 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3315 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003316 """
3317 self.assertRaises(ValueError, load_crl, 100, crlData)
3318
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003319 def test_load_crl_bad_data(self):
3320 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003321 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3322 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003323 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003324 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003325
Dominic Chenf05b2122015-10-13 16:32:35 +00003326 def test_dump_crl(self):
3327 """
3328 The dumped CRL matches the original input.
3329 """
3330 crl = load_crl(FILETYPE_PEM, crlData)
3331 buf = dump_crl(FILETYPE_PEM, crl)
3332 assert buf == crlData
3333
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003334
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003335class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003336 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003337 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003338 """
3339 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3340 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003341 intermediate_server_cert = load_certificate(
3342 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003343
3344 def test_valid(self):
3345 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003346 :py:obj:`verify_certificate` returns ``None`` when called with a
3347 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003348 """
3349 store = X509Store()
3350 store.add_cert(self.root_cert)
3351 store.add_cert(self.intermediate_cert)
3352 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003353 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003354
3355 def test_reuse(self):
3356 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003357 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003358 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003359 """
3360 store = X509Store()
3361 store.add_cert(self.root_cert)
3362 store.add_cert(self.intermediate_cert)
3363 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003364 self.assertEqual(store_ctx.verify_certificate(), None)
3365 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003366
3367 def test_trusted_self_signed(self):
3368 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003369 :py:obj:`verify_certificate` returns ``None`` when called with a
3370 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003371 """
3372 store = X509Store()
3373 store.add_cert(self.root_cert)
3374 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003375 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003376
3377 def test_untrusted_self_signed(self):
3378 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003379 :py:obj:`verify_certificate` raises error when a self-signed
3380 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003381 """
3382 store = X509Store()
3383 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003384 with pytest.raises(X509StoreContextError) as exc:
3385 store_ctx.verify_certificate()
3386
3387 assert exc.value.args[0][2] == 'self signed certificate'
3388 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003389
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003390 def test_invalid_chain_no_root(self):
3391 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003392 :py:obj:`verify_certificate` raises error when a root certificate is
3393 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003394 """
3395 store = X509Store()
3396 store.add_cert(self.intermediate_cert)
3397 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003398
3399 with pytest.raises(X509StoreContextError) as exc:
3400 store_ctx.verify_certificate()
3401
3402 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3403 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003404
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003405 def test_invalid_chain_no_intermediate(self):
3406 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003407 :py:obj:`verify_certificate` raises error when an intermediate
3408 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003409 """
3410 store = X509Store()
3411 store.add_cert(self.root_cert)
3412 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003413
Alex Gaynor85b49702015-09-05 16:30:59 -04003414 with pytest.raises(X509StoreContextError) as exc:
3415 store_ctx.verify_certificate()
3416
3417 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3418 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003419
Stephen Holsapple46a09252015-02-12 14:45:43 -08003420 def test_modification_pre_verify(self):
3421 """
3422 :py:obj:`verify_certificate` can use a store context modified after
3423 instantiation.
3424 """
3425 store_bad = X509Store()
3426 store_bad.add_cert(self.intermediate_cert)
3427 store_good = X509Store()
3428 store_good.add_cert(self.root_cert)
3429 store_good.add_cert(self.intermediate_cert)
3430 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003431
3432 with pytest.raises(X509StoreContextError) as exc:
3433 store_ctx.verify_certificate()
3434
3435 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3436 assert exc.value.certificate.get_subject().CN == 'intermediate'
3437
Stephen Holsapple46a09252015-02-12 14:45:43 -08003438 store_ctx.set_store(store_good)
3439 self.assertEqual(store_ctx.verify_certificate(), None)
3440
3441
James Yonan7c2e5d32010-02-27 05:45:50 -07003442class SignVerifyTests(TestCase):
3443 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003444 Tests for :py:obj:`OpenSSL.crypto.sign` and
3445 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003446 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003447
James Yonan7c2e5d32010-02-27 05:45:50 -07003448 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003449 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003450 :py:obj:`sign` generates a cryptographic signature which
3451 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003452 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003453 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003454 "It was a bright cold day in April, and the clocks were striking "
3455 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3456 "effort to escape the vile wind, slipped quickly through the "
3457 "glass doors of Victory Mansions, though not quickly enough to "
3458 "prevent a swirl of gritty dust from entering along with him.")
3459
3460 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003461 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003462 # verify the content with this cert
3463 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3464 # certificate unrelated to priv_key, used to trigger an error
3465 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003466
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003467 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003468 sig = sign(priv_key, content, digest)
3469
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003470 # Verify the signature of content, will throw an exception if
3471 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003472 verify(good_cert, sig, content, digest)
3473
3474 # This should fail because the certificate doesn't match the
3475 # private key that was used to sign the content.
3476 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3477
3478 # This should fail because we've "tainted" the content after
3479 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003480 self.assertRaises(
3481 Error, verify,
3482 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003483
3484 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003485 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003486 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003487 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003488 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003489
Abraham Martinc5484ba2015-03-25 15:33:05 +00003490 def test_sign_verify_with_text(self):
3491 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003492 :py:obj:`sign` generates a cryptographic signature which
3493 :py:obj:`verify` can check. Deprecation warnings raised because using
3494 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003495 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003496 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003497 b"It was a bright cold day in April, and the clocks were striking "
3498 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3499 b"effort to escape the vile wind, slipped quickly through the "
3500 b"glass doors of Victory Mansions, though not quickly enough to "
3501 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003502 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003503
3504 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3505 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3506 for digest in ['md5', 'sha1']:
3507 with catch_warnings(record=True) as w:
3508 simplefilter("always")
3509 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003510
3511 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003512 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003513 WARNING_TYPE_EXPECTED
3514 ),
3515 str(w[-1].message)
3516 )
3517 self.assertIs(w[-1].category, DeprecationWarning)
3518
Abraham Martinc5484ba2015-03-25 15:33:05 +00003519 with catch_warnings(record=True) as w:
3520 simplefilter("always")
3521 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003522
3523 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003524 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003525 WARNING_TYPE_EXPECTED
3526 ),
3527 str(w[-1].message)
3528 )
3529 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003530
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003531 def test_sign_nulls(self):
3532 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003533 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003534 """
3535 content = b("Watch out! \0 Did you see it?")
3536 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3537 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3538 sig = sign(priv_key, content, "sha1")
3539 verify(good_cert, sig, content, "sha1")
3540
Colleen Murphye09399b2016-03-01 17:40:49 -08003541 def test_sign_with_large_key(self):
3542 """
3543 :py:obj:`sign` produces a signature for a string when using a long key.
3544 """
3545 content = b(
3546 "It was a bright cold day in April, and the clocks were striking "
3547 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3548 "effort to escape the vile wind, slipped quickly through the "
3549 "glass doors of Victory Mansions, though not quickly enough to "
3550 "prevent a swirl of gritty dust from entering along with him.")
3551
3552 priv_key = load_privatekey(FILETYPE_PEM, large_key_pem)
3553 sign(priv_key, content, "sha1")
3554
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003555
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003556class EllipticCurveTests(TestCase):
3557 """
3558 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3559 :py:obj:`get_elliptic_curves`.
3560 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003561
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003562 def test_set(self):
3563 """
3564 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3565 """
3566 self.assertIsInstance(get_elliptic_curves(), set)
3567
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003568 def test_some_curves(self):
3569 """
3570 If :py:mod:`cryptography` has elliptic curve support then the set
3571 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3572 it.
3573
3574 There could be an OpenSSL that violates this assumption. If so, this
3575 test will fail and we'll find out.
3576 """
3577 curves = get_elliptic_curves()
3578 if lib.Cryptography_HAS_EC:
3579 self.assertTrue(curves)
3580 else:
3581 self.assertFalse(curves)
3582
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003583 def test_a_curve(self):
3584 """
3585 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3586 supported curve.
3587 """
3588 curves = get_elliptic_curves()
3589 if curves:
3590 curve = next(iter(curves))
3591 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3592 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003593 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003594
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003595 def test_not_a_curve(self):
3596 """
3597 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3598 with a name which does not identify a supported curve.
3599 """
3600 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003601 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003602
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003603 def test_repr(self):
3604 """
3605 The string representation of a curve object includes simply states the
3606 object is a curve and what its name is.
3607 """
3608 curves = get_elliptic_curves()
3609 if curves:
3610 curve = next(iter(curves))
3611 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3612
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003613 def test_to_EC_KEY(self):
3614 """
3615 The curve object can export a version of itself as an EC_KEY* via the
3616 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3617 """
3618 curves = get_elliptic_curves()
3619 if curves:
3620 curve = next(iter(curves))
3621 # It's not easy to assert anything about this object. However, see
3622 # leakcheck/crypto.py for a test that demonstrates it at least does
3623 # not leak memory.
3624 curve._to_EC_KEY()
3625
3626
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003627class EllipticCurveFactory(object):
3628 """
3629 A helper to get the names of two curves.
3630 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003631
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003632 def __init__(self):
3633 curves = iter(get_elliptic_curves())
3634 try:
3635 self.curve_name = next(curves).name
3636 self.another_curve_name = next(curves).name
3637 except StopIteration:
3638 self.curve_name = self.another_curve_name = None
3639
3640
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003641class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3642 """
3643 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3644 """
3645 curve_factory = EllipticCurveFactory()
3646
3647 if curve_factory.curve_name is None:
3648 skip = "There are no curves available there can be no curve objects."
3649
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003650 def anInstance(self):
3651 """
3652 Get the curve object for an arbitrary curve supported by the system.
3653 """
3654 return get_elliptic_curve(self.curve_factory.curve_name)
3655
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003656 def anotherInstance(self):
3657 """
3658 Get the curve object for an arbitrary curve supported by the system -
3659 but not the one returned by C{anInstance}.
3660 """
3661 return get_elliptic_curve(self.curve_factory.another_curve_name)
3662
3663
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003664class EllipticCurveHashTests(TestCase):
3665 """
3666 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3667 as an item in a :py:type:`dict` or :py:type:`set`).
3668 """
3669 curve_factory = EllipticCurveFactory()
3670
3671 if curve_factory.curve_name is None:
3672 skip = "There are no curves available there can be no curve objects."
3673
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003674 def test_contains(self):
3675 """
3676 The ``in`` operator reports that a :py:type:`set` containing a curve
3677 does contain that curve.
3678 """
3679 curve = get_elliptic_curve(self.curve_factory.curve_name)
3680 curves = set([curve])
3681 self.assertIn(curve, curves)
3682
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003683 def test_does_not_contain(self):
3684 """
3685 The ``in`` operator reports that a :py:type:`set` not containing a
3686 curve does not contain that curve.
3687 """
3688 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003689 curves = set([
3690 get_elliptic_curve(self.curve_factory.another_curve_name)
3691 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003692 self.assertNotIn(curve, curves)
3693
3694
Rick Dean5b7b6372009-04-01 11:34:06 -05003695if __name__ == '__main__':
3696 main()