blob: ad6df1d260a9f452348b153b7e0c01539a2ef830 [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
57GOOD_DIGEST = "MD5"
58BAD_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
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400423
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400424class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400425 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900426 Tests for :py:class:`OpenSSL.crypto.X509Extension`.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400427 """
428
429 def setUp(self):
430 """
431 Create a new private key and start a certificate request (for a test
432 method to finish in one way or another).
433 """
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800434 super(X509ExtTests, self).setUp()
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400435 # Basic setup stuff to generate a certificate
436 self.pkey = PKey()
437 self.pkey.generate_key(TYPE_RSA, 384)
438 self.req = X509Req()
439 self.req.set_pubkey(self.pkey)
440 # Authority good you have.
441 self.req.get_subject().commonName = "Yoda root CA"
442 self.x509 = X509()
443 self.subject = self.x509.get_subject()
444 self.subject.commonName = self.req.get_subject().commonName
445 self.x509.set_issuer(self.subject)
446 self.x509.set_pubkey(self.pkey)
Alex Gaynor85b49702015-09-05 16:30:59 -0400447 now = datetime.now()
448 expire = datetime.now() + timedelta(days=100)
449 self.x509.set_notBefore(now.strftime("%Y%m%d%H%M%SZ").encode())
450 self.x509.set_notAfter(expire.strftime("%Y%m%d%H%M%SZ").encode())
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400451
Jean-Paul Calderoneef9a3dc2013-03-02 16:33:32 -0800452 def tearDown(self):
453 """
454 Forget all of the pyOpenSSL objects so they can be garbage collected,
455 their memory released, and not interfere with the leak detection code.
456 """
457 self.pkey = self.req = self.x509 = self.subject = None
458 super(X509ExtTests, self).tearDown()
459
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400460 def test_str(self):
461 """
Alex Gaynor31287502015-09-05 16:11:27 -0400462 The string representation of :py:class:`X509Extension` instances as
463 returned by :py:data:`str` includes stuff.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400464 """
465 # This isn't necessarily the best string representation. Perhaps it
466 # will be changed/improved in the future.
467 self.assertEquals(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400468 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -0400469 'CA:FALSE')
470
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400471 def test_type(self):
472 """
Alex Gaynor31287502015-09-05 16:11:27 -0400473 :py:class:`X509Extension` and :py:class:`X509ExtensionType` refer to
474 the same type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400475 """
476 self.assertIdentical(X509Extension, X509ExtensionType)
477 self.assertConsistentType(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400478 X509Extension,
479 'X509Extension', b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400480
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500481 def test_construction(self):
482 """
Alex Gaynor31287502015-09-05 16:11:27 -0400483 :py:class:`X509Extension` accepts an extension type name, a critical
484 flag, and an extension value and returns an
485 :py:class:`X509ExtensionType` instance.
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500486 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400487 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500488 self.assertTrue(
489 isinstance(basic, X509ExtensionType),
490 "%r is of type %r, should be %r" % (
491 basic, type(basic), X509ExtensionType))
492
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400493 comment = X509Extension(
494 b('nsComment'), False, b('pyOpenSSL unit test'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500495 self.assertTrue(
496 isinstance(comment, X509ExtensionType),
497 "%r is of type %r, should be %r" % (
498 comment, type(comment), X509ExtensionType))
499
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500500 def test_invalid_extension(self):
501 """
Alex Gaynor31287502015-09-05 16:11:27 -0400502 :py:class:`X509Extension` raises something if it is passed a bad
503 extension name or value.
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500504 """
505 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400506 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500507 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400508 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500509
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500510 # Exercise a weird one (an extension which uses the r2i method). This
511 # exercises the codepath that requires a non-NULL ctx to be passed to
512 # X509V3_EXT_nconf. It can't work now because we provide no
513 # configuration database. It might be made to work in the future.
514 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400515 Error, X509Extension, b('proxyCertInfo'), True,
516 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500517
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500518 def test_get_critical(self):
519 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900520 :py:meth:`X509ExtensionType.get_critical` returns the value of the
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500521 extension's critical flag.
522 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400523 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500524 self.assertTrue(ext.get_critical())
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400525 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500526 self.assertFalse(ext.get_critical())
527
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500528 def test_get_short_name(self):
529 """
Alex Gaynor31287502015-09-05 16:11:27 -0400530 :py:meth:`X509ExtensionType.get_short_name` returns a string giving the
531 short type name of the extension.
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500532 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400533 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
534 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
535 ext = X509Extension(b('nsComment'), True, b('foo bar'))
536 self.assertEqual(ext.get_short_name(), b('nsComment'))
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500537
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400538 def test_get_data(self):
539 """
Alex Gaynor31287502015-09-05 16:11:27 -0400540 :py:meth:`X509Extension.get_data` returns a string giving the data of
541 the extension.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400542 """
543 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
544 # Expect to get back the DER encoded form of CA:true.
545 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
546
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400547 def test_get_data_wrong_args(self):
548 """
Alex Gaynor31287502015-09-05 16:11:27 -0400549 :py:meth:`X509Extension.get_data` raises :py:exc:`TypeError` if passed
550 any arguments.
Jean-Paul Calderone5a9e4612011-04-01 18:27:45 -0400551 """
552 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
553 self.assertRaises(TypeError, ext.get_data, None)
554 self.assertRaises(TypeError, ext.get_data, "foo")
555 self.assertRaises(TypeError, ext.get_data, 7)
556
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400557 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500558 """
Alex Gaynor31287502015-09-05 16:11:27 -0400559 The :py:data:`subject` parameter to :py:class:`X509Extension` may be
560 provided for an extension which does not use it and is ignored in this
561 case.
Rick Dean47262da2009-07-08 16:17:17 -0500562 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400563 ext1 = X509Extension(
564 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400565 self.x509.add_extensions([ext1])
566 self.x509.sign(self.pkey, 'sha1')
567 # This is a little lame. Can we think of a better way?
568 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400569 self.assertTrue(b('X509v3 Basic Constraints:') in text)
570 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400571
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400572 def test_subject(self):
573 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900574 If an extension requires a subject, the :py:data:`subject` parameter to
575 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400576 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400577 ext3 = X509Extension(
578 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400579 self.x509.add_extensions([ext3])
580 self.x509.sign(self.pkey, 'sha1')
581 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400582 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400583
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400584 def test_missing_subject(self):
585 """
Alex Gaynor31287502015-09-05 16:11:27 -0400586 If an extension requires a subject and the :py:data:`subject` parameter
587 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400588 """
589 self.assertRaises(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400590 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400591
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400592 def test_invalid_subject(self):
593 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900594 If the :py:data:`subject` parameter is given a value which is not an
595 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400596 """
597 for badObj in [True, object(), "hello", [], self]:
598 self.assertRaises(
599 TypeError,
600 X509Extension,
601 'basicConstraints', False, 'CA:TRUE', subject=badObj)
602
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400603 def test_unused_issuer(self):
604 """
Alex Gaynor31287502015-09-05 16:11:27 -0400605 The :py:data:`issuer` parameter to :py:class:`X509Extension` may be
606 provided for an extension which does not use it and is ignored in this
607 case.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400608 """
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400609 ext1 = X509Extension(
610 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400611 self.x509.add_extensions([ext1])
612 self.x509.sign(self.pkey, 'sha1')
613 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400614 self.assertTrue(b('X509v3 Basic Constraints:') in text)
615 self.assertTrue(b('CA:TRUE') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400616
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400617 def test_issuer(self):
618 """
Alex Gaynor3b0ee972014-11-15 09:17:33 -0800619 If an extension requires an issuer, the :py:data:`issuer` parameter to
Jonathan Ballet648875f2011-07-16 14:14:58 +0900620 :py:class:`X509Extension` provides its value.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400621 """
622 ext2 = X509Extension(
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400623 b('authorityKeyIdentifier'), False, b('issuer:always'),
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400624 issuer=self.x509)
625 self.x509.add_extensions([ext2])
626 self.x509.sign(self.pkey, 'sha1')
627 text = dump_certificate(FILETYPE_TEXT, self.x509)
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400628 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
629 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400630
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400631 def test_missing_issuer(self):
632 """
Alex Gaynor31287502015-09-05 16:11:27 -0400633 If an extension requires an issue and the :py:data:`issuer` parameter
634 is given no value, something happens.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400635 """
636 self.assertRaises(
637 Error,
638 X509Extension,
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400639 b('authorityKeyIdentifier'), False,
640 b('keyid:always,issuer:always'))
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400641
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400642 def test_invalid_issuer(self):
643 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900644 If the :py:data:`issuer` parameter is given a value which is not an
645 :py:class:`X509` instance, :py:exc:`TypeError` is raised.
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400646 """
647 for badObj in [True, object(), "hello", [], self]:
648 self.assertRaises(
649 TypeError,
650 X509Extension,
651 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
652 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500653
654
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400655class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500656 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900657 Unit tests for :py:class:`OpenSSL.crypto.PKey`.
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500658 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400659
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400660 def test_type(self):
661 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900662 :py:class:`PKey` and :py:class:`PKeyType` refer to the same type object
663 and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400664 """
665 self.assertIdentical(PKey, PKeyType)
666 self.assertConsistentType(PKey, 'PKey')
667
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500668 def test_construction(self):
669 """
Alex Gaynor31287502015-09-05 16:11:27 -0400670 :py:class:`PKey` takes no arguments and returns a new :py:class:`PKey`
671 instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500672 """
673 self.assertRaises(TypeError, PKey, None)
674 key = PKey()
675 self.assertTrue(
676 isinstance(key, PKeyType),
677 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
678
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500679 def test_pregeneration(self):
680 """
Alex Gaynor31287502015-09-05 16:11:27 -0400681 :py:attr:`PKeyType.bits` and :py:attr:`PKeyType.type` return
682 :py:data:`0` before the key is generated. :py:attr:`PKeyType.check`
683 raises :py:exc:`TypeError` before the key is generated.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500684 """
685 key = PKey()
686 self.assertEqual(key.type(), 0)
687 self.assertEqual(key.bits(), 0)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400688 self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500689
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500690 def test_failedGeneration(self):
691 """
Alex Gaynor31287502015-09-05 16:11:27 -0400692 :py:meth:`PKeyType.generate_key` takes two arguments, the first giving
693 the key type as one of :py:data:`TYPE_RSA` or :py:data:`TYPE_DSA` and
694 the second giving the number of bits to generate. If an invalid type
695 is specified or generation fails, :py:exc:`Error` is raised. If an
696 invalid number of bits is specified, :py:exc:`ValueError` or
697 :py:exc:`Error` is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500698 """
699 key = PKey()
700 self.assertRaises(TypeError, key.generate_key)
701 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
702 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
703 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500704
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500705 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
706 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500707
708 # XXX RSA generation for small values of bits is fairly buggy in a wide
709 # range of OpenSSL versions. I need to figure out what the safe lower
710 # bound for a reasonable number of OpenSSL versions is and explicitly
711 # check for that in the wrapper. The failure behavior is typically an
712 # infinite loop inside OpenSSL.
713
714 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500715
716 # XXX DSA generation seems happy with any number of bits. The DSS
717 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
718 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500719 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500720 # So, it doesn't seem possible to make generate_key fail for
721 # TYPE_DSA with a bits argument which is at least an int.
722
723 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
724
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500725 def test_rsaGeneration(self):
726 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900727 :py:meth:`PKeyType.generate_key` generates an RSA key when passed
728 :py:data:`TYPE_RSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500729 """
730 bits = 128
731 key = PKey()
732 key.generate_key(TYPE_RSA, bits)
733 self.assertEqual(key.type(), TYPE_RSA)
734 self.assertEqual(key.bits(), bits)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -0400735 self.assertTrue(key.check())
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500736
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500737 def test_dsaGeneration(self):
738 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900739 :py:meth:`PKeyType.generate_key` generates a DSA key when passed
740 :py:data:`TYPE_DSA` as a type and a reasonable number of bits.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500741 """
742 # 512 is a magic number. The DSS (Digital Signature Standard)
743 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
744 # will silently promote any value below 512 to 512.
745 bits = 512
746 key = PKey()
747 key.generate_key(TYPE_DSA, bits)
Jean-Paul Calderonef6745b32013-03-01 15:08:46 -0800748 # self.assertEqual(key.type(), TYPE_DSA)
749 # self.assertEqual(key.bits(), bits)
750 # self.assertRaises(TypeError, key.check)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500751
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500752 def test_regeneration(self):
753 """
Alex Gaynor31287502015-09-05 16:11:27 -0400754 :py:meth:`PKeyType.generate_key` can be called multiple times on the
755 same key to generate new keys.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500756 """
757 key = PKey()
758 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
Alex Gaynor7f636492015-09-04 13:26:52 -0400759 key.generate_key(type, bits)
760 self.assertEqual(key.type(), type)
761 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500762
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400763 def test_inconsistentKey(self):
764 """
Alex Gaynor31287502015-09-05 16:11:27 -0400765 :py:`PKeyType.check` returns :py:exc:`Error` if the key is not
766 consistent.
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400767 """
768 key = load_privatekey(FILETYPE_PEM, inconsistentPrivateKeyPEM)
Jean-Paul Calderoned338e4e2009-05-13 15:45:07 -0400769 self.assertRaises(Error, key.check)
Jean-Paul Calderone55ec1712009-05-13 14:14:30 -0400770
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400771 def test_check_wrong_args(self):
772 """
Alex Gaynor31287502015-09-05 16:11:27 -0400773 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if called with any
774 arguments.
Jean-Paul Calderonee81020e2011-06-12 21:48:57 -0400775 """
776 self.assertRaises(TypeError, PKey().check, None)
777 self.assertRaises(TypeError, PKey().check, object())
778 self.assertRaises(TypeError, PKey().check, 1)
779
Jean-Paul Calderone02d01972011-10-31 10:39:29 -0400780 def test_check_public_key(self):
781 """
782 :py:meth:`PKeyType.check` raises :py:exc:`TypeError` if only the public
783 part of the key is available.
784 """
785 # A trick to get a public-only key
786 key = PKey()
787 key.generate_key(TYPE_RSA, 512)
788 cert = X509()
789 cert.set_pubkey(key)
790 pub = cert.get_pubkey()
791 self.assertRaises(TypeError, pub.check)
792
793
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400794class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500795 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900796 Unit tests for :py:class:`OpenSSL.crypto.X509Name`.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500797 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -0400798
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500799 def _x509name(self, **attrs):
800 # XXX There's no other way to get a new X509Name yet.
801 name = X509().get_subject()
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400802 attrs = list(attrs.items())
Alex Gaynor85b49702015-09-05 16:30:59 -0400803
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500804 # Make the order stable - order matters!
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400805 def key(attr):
806 return attr[1]
807 attrs.sort(key=key)
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500808 for k, v in attrs:
809 setattr(name, k, v)
810 return name
811
Rick Deane15b1472009-07-09 15:53:42 -0500812 def test_type(self):
813 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900814 The type of X509Name objects is :py:class:`X509NameType`.
Rick Deane15b1472009-07-09 15:53:42 -0500815 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400816 self.assertIdentical(X509Name, X509NameType)
817 self.assertEqual(X509NameType.__name__, 'X509Name')
818 self.assertTrue(isinstance(X509NameType, type))
819
Rick Deane15b1472009-07-09 15:53:42 -0500820 name = self._x509name()
821 self.assertTrue(
822 isinstance(name, X509NameType),
823 "%r is of type %r, should be %r" % (
824 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500825
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400826 def test_onlyStringAttributes(self):
827 """
Alex Gaynor31287502015-09-05 16:11:27 -0400828 Attempting to set a non-:py:data:`str` attribute name on an
829 :py:class:`X509NameType` instance causes :py:exc:`TypeError` to be
830 raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400831 """
832 name = self._x509name()
833 # Beyond these cases, you may also think that unicode should be
Alex Gaynor31287502015-09-05 16:11:27 -0400834 # rejected. Sorry, you're wrong. unicode is automatically converted
835 # to str outside of the control of X509Name, so there's no way to
836 # reject it.
Jean-Paul Calderoneff363be2013-03-03 10:21:23 -0800837
Alex Gaynor31287502015-09-05 16:11:27 -0400838 # Also, this used to test str subclasses, but that test is less
839 # relevant now that the implementation is in Python instead of C. Also
840 # PyPy automatically converts str subclasses to str when they are
841 # passed to setattr, so we can't test it on PyPy. Apparently CPython
842 # does this sometimes as well.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400843 self.assertRaises(TypeError, setattr, name, None, "hello")
844 self.assertRaises(TypeError, setattr, name, 30, "hello")
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400845
846 def test_setInvalidAttribute(self):
847 """
Alex Gaynor31287502015-09-05 16:11:27 -0400848 Attempting to set any attribute name on an :py:class:`X509NameType`
849 instance for which no corresponding NID is defined causes
850 :py:exc:`AttributeError` to be raised.
Jean-Paul Calderone9ce9afb2011-04-22 18:16:22 -0400851 """
852 name = self._x509name()
853 self.assertRaises(AttributeError, setattr, name, "no such thing", None)
854
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500855 def test_attributes(self):
856 """
Alex Gaynor31287502015-09-05 16:11:27 -0400857 :py:class:`X509NameType` instances have attributes for each standard
858 (?) X509Name field.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500859 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500860 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500861 name.commonName = "foo"
862 self.assertEqual(name.commonName, "foo")
863 self.assertEqual(name.CN, "foo")
864 name.CN = "baz"
865 self.assertEqual(name.commonName, "baz")
866 self.assertEqual(name.CN, "baz")
867 name.commonName = "bar"
868 self.assertEqual(name.commonName, "bar")
869 self.assertEqual(name.CN, "bar")
870 name.CN = "quux"
871 self.assertEqual(name.commonName, "quux")
872 self.assertEqual(name.CN, "quux")
873
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500874 def test_copy(self):
875 """
Alex Gaynor31287502015-09-05 16:11:27 -0400876 :py:class:`X509Name` creates a new :py:class:`X509NameType` instance
877 with all the same attributes as an existing :py:class:`X509NameType`
878 instance when called with one.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500879 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500880 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500881
882 copy = X509Name(name)
883 self.assertEqual(copy.commonName, "foo")
884 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500885
886 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500887 copy.commonName = "baz"
888 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500889
890 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500891 name.emailAddress = "quux@example.com"
892 self.assertEqual(copy.emailAddress, "bar@example.com")
893
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500894 def test_repr(self):
895 """
Alex Gaynor31287502015-09-05 16:11:27 -0400896 :py:func:`repr` passed an :py:class:`X509NameType` instance should
897 return a string containing a description of the type and the NIDs which
898 have been set on it.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500899 """
900 name = self._x509name(commonName="foo", emailAddress="bar")
901 self.assertEqual(
902 repr(name),
903 "<X509Name object '/emailAddress=bar/CN=foo'>")
904
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500905 def test_comparison(self):
906 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900907 :py:class:`X509NameType` instances should compare based on their NIDs.
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500908 """
909 def _equality(a, b, assertTrue, assertFalse):
910 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
911 assertFalse(a != b)
912 assertTrue(b == a)
913 assertFalse(b != a)
914
915 def assertEqual(a, b):
916 _equality(a, b, self.assertTrue, self.assertFalse)
917
918 # Instances compare equal to themselves.
919 name = self._x509name()
920 assertEqual(name, name)
921
922 # Empty instances should compare equal to each other.
923 assertEqual(self._x509name(), self._x509name())
924
925 # Instances with equal NIDs should compare equal to each other.
926 assertEqual(self._x509name(commonName="foo"),
927 self._x509name(commonName="foo"))
928
929 # Instance with equal NIDs set using different aliases should compare
930 # equal to each other.
931 assertEqual(self._x509name(commonName="foo"),
932 self._x509name(CN="foo"))
933
934 # Instances with more than one NID with the same values should compare
935 # equal to each other.
936 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
937 self._x509name(commonName="foo", OU="bar"))
938
939 def assertNotEqual(a, b):
940 _equality(a, b, self.assertFalse, self.assertTrue)
941
942 # Instances with different values for the same NID should not compare
943 # equal to each other.
944 assertNotEqual(self._x509name(CN="foo"),
945 self._x509name(CN="bar"))
946
947 # Instances with different NIDs should not compare equal to each other.
948 assertNotEqual(self._x509name(CN="foo"),
949 self._x509name(OU="foo"))
950
951 def _inequality(a, b, assertTrue, assertFalse):
952 assertTrue(a < b)
953 assertTrue(a <= b)
954 assertTrue(b > a)
955 assertTrue(b >= a)
956 assertFalse(a > b)
957 assertFalse(a >= b)
958 assertFalse(b < a)
959 assertFalse(b <= a)
960
961 def assertLessThan(a, b):
962 _inequality(a, b, self.assertTrue, self.assertFalse)
963
964 # An X509Name with a NID with a value which sorts less than the value
965 # of the same NID on another X509Name compares less than the other
966 # X509Name.
967 assertLessThan(self._x509name(CN="abc"),
968 self._x509name(CN="def"))
969
970 def assertGreaterThan(a, b):
971 _inequality(a, b, self.assertFalse, self.assertTrue)
972
973 # An X509Name with a NID with a value which sorts greater than the
974 # value of the same NID on another X509Name compares greater than the
975 # other X509Name.
976 assertGreaterThan(self._x509name(CN="def"),
977 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500978
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400979 def test_hash(self):
980 """
Alex Gaynor31287502015-09-05 16:11:27 -0400981 :py:meth:`X509Name.hash` returns an integer hash based on the value of
982 the name.
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400983 """
984 a = self._x509name(CN="foo")
985 b = self._x509name(CN="foo")
986 self.assertEqual(a.hash(), b.hash())
987 a.CN = "bar"
988 self.assertNotEqual(a.hash(), b.hash())
989
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400990 def test_der(self):
991 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900992 :py:meth:`X509Name.der` returns the DER encoded form of the name.
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400993 """
994 a = self._x509name(CN="foo", C="US")
995 self.assertEqual(
996 a.der(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -0400997 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
D.S. Ljungmark5533e252014-05-31 13:18:41 +0200998 '1\x0c0\n\x06\x03U\x04\x03\x0c\x03foo'))
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400999
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001000 def test_get_components(self):
1001 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001002 :py:meth:`X509Name.get_components` returns a :py:data:`list` of
1003 two-tuples of :py:data:`str`
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001004 giving the NIDs and associated values which make up the name.
1005 """
1006 a = self._x509name()
1007 self.assertEqual(a.get_components(), [])
1008 a.CN = "foo"
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001009 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001010 a.organizationalUnitName = "bar"
1011 self.assertEqual(
1012 a.get_components(),
Jean-Paul Calderone2ac721b2010-08-22 19:20:00 -04001013 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -04001014
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001015 def test_load_nul_byte_attribute(self):
1016 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001017 An :py:class:`OpenSSL.crypto.X509Name` from an
1018 :py:class:`OpenSSL.crypto.X509` instance loaded from a file can have a
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001019 NUL byte in the value of one of its attributes.
1020 """
1021 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
1022 subject = cert.get_subject()
1023 self.assertEqual(
Jean-Paul Calderone06754fc2013-08-23 15:47:47 -04001024 "null.python.org\x00example.org", subject.commonName)
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001025
Jean-Paul Calderone5300d6a2013-12-29 16:36:50 -05001026 def test_setAttributeFailure(self):
1027 """
1028 If the value of an attribute cannot be set for some reason then
1029 :py:class:`OpenSSL.crypto.Error` is raised.
1030 """
1031 name = self._x509name()
1032 # This value is too long
1033 self.assertRaises(Error, setattr, name, "O", b"x" * 512)
1034
1035
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001036class _PKeyInteractionTestsMixin:
1037 """
1038 Tests which involve another thing and a PKey.
1039 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001040
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001041 def signable(self):
1042 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001043 Return something with a :py:meth:`set_pubkey`, :py:meth:`set_pubkey`,
1044 and :py:meth:`sign` method.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001045 """
1046 raise NotImplementedError()
1047
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001048 def test_signWithUngenerated(self):
1049 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001050 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1051 :py:class:`PKey` with no parts.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001052 """
1053 request = self.signable()
1054 key = PKey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001055 self.assertRaises(ValueError, request.sign, key, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001056
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001057 def test_signWithPublicKey(self):
1058 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001059 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when pass a
1060 :py:class:`PKey` with no private part as the signing key.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001061 """
1062 request = self.signable()
1063 key = PKey()
1064 key.generate_key(TYPE_RSA, 512)
1065 request.set_pubkey(key)
1066 pub = request.get_pubkey()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001067 self.assertRaises(ValueError, request.sign, pub, GOOD_DIGEST)
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001068
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001069 def test_signWithUnknownDigest(self):
1070 """
Alex Gaynor31287502015-09-05 16:11:27 -04001071 :py:meth:`X509Req.sign` raises :py:exc:`ValueError` when passed a
1072 digest name which is not known.
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001073 """
1074 request = self.signable()
1075 key = PKey()
1076 key.generate_key(TYPE_RSA, 512)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001077 self.assertRaises(ValueError, request.sign, key, BAD_DIGEST)
Jean-Paul Calderonecc05a912010-08-03 18:24:19 -04001078
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001079 def test_sign(self):
1080 """
Alex Gaynor31287502015-09-05 16:11:27 -04001081 :py:meth:`X509Req.sign` succeeds when passed a private key object and a
1082 valid digest function. :py:meth:`X509Req.verify` can be used to check
1083 the signature.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001084 """
1085 request = self.signable()
1086 key = PKey()
1087 key.generate_key(TYPE_RSA, 512)
1088 request.set_pubkey(key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001089 request.sign(key, GOOD_DIGEST)
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04001090 # If the type has a verify method, cover that too.
1091 if getattr(request, 'verify', None) is not None:
1092 pub = request.get_pubkey()
1093 self.assertTrue(request.verify(pub))
1094 # Make another key that won't verify.
1095 key = PKey()
1096 key.generate_key(TYPE_RSA, 512)
1097 self.assertRaises(Error, request.verify, key)
1098
1099
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001100class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001101 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001102 Tests for :py:class:`OpenSSL.crypto.X509Req`.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001103 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001104
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001105 def signable(self):
1106 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001107 Create and return a new :py:class:`X509Req`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001108 """
1109 return X509Req()
1110
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001111 def test_type(self):
1112 """
Alex Gaynor31287502015-09-05 16:11:27 -04001113 :py:obj:`X509Req` and :py:obj:`X509ReqType` refer to the same type
1114 object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001115 """
1116 self.assertIdentical(X509Req, X509ReqType)
1117 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001118
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001119 def test_construction(self):
1120 """
Alex Gaynor31287502015-09-05 16:11:27 -04001121 :py:obj:`X509Req` takes no arguments and returns an
1122 :py:obj:`X509ReqType` instance.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001123 """
1124 request = X509Req()
Alex Gaynor31287502015-09-05 16:11:27 -04001125 assert isinstance(request, X509ReqType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001126
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001127 def test_version(self):
1128 """
Alex Gaynor31287502015-09-05 16:11:27 -04001129 :py:obj:`X509ReqType.set_version` sets the X.509 version of the
1130 certificate request. :py:obj:`X509ReqType.get_version` returns the
1131 X.509 version of the certificate request. The initial value of the
1132 version is 0.
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -05001133 """
1134 request = X509Req()
1135 self.assertEqual(request.get_version(), 0)
1136 request.set_version(1)
1137 self.assertEqual(request.get_version(), 1)
1138 request.set_version(3)
1139 self.assertEqual(request.get_version(), 3)
1140
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001141 def test_version_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001142 """
Alex Gaynor31287502015-09-05 16:11:27 -04001143 :py:obj:`X509ReqType.set_version` raises :py:obj:`TypeError` if called
1144 with the wrong number of arguments or with a non-:py:obj:`int`
1145 argument. :py:obj:`X509ReqType.get_version` raises :py:obj:`TypeError`
1146 if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001147 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001148 request = X509Req()
1149 self.assertRaises(TypeError, request.set_version)
1150 self.assertRaises(TypeError, request.set_version, "foo")
1151 self.assertRaises(TypeError, request.set_version, 1, 2)
1152 self.assertRaises(TypeError, request.get_version, None)
1153
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001154 def test_get_subject(self):
1155 """
Alex Gaynor31287502015-09-05 16:11:27 -04001156 :py:obj:`X509ReqType.get_subject` returns an :py:obj:`X509Name` for the
1157 subject of the request and which is valid even after the request object
1158 is otherwise dead.
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001159 """
1160 request = X509Req()
1161 subject = request.get_subject()
Alex Gaynor31287502015-09-05 16:11:27 -04001162 assert isinstance(subject, X509NameType)
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -05001163 subject.commonName = "foo"
1164 self.assertEqual(request.get_subject().commonName, "foo")
1165 del request
1166 subject.commonName = "bar"
1167 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001168
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001169 def test_get_subject_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001170 """
Alex Gaynor31287502015-09-05 16:11:27 -04001171 :py:obj:`X509ReqType.get_subject` raises :py:obj:`TypeError` if called
1172 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04001173 """
Jean-Paul Calderone54e49e92010-07-30 11:04:46 -04001174 request = X509Req()
1175 self.assertRaises(TypeError, request.get_subject, None)
1176
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001177 def test_add_extensions(self):
1178 """
Alex Gaynor31287502015-09-05 16:11:27 -04001179 :py:obj:`X509Req.add_extensions` accepts a :py:obj:`list` of
1180 :py:obj:`X509Extension` instances and adds them to the X509 request.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001181 """
1182 request = X509Req()
1183 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001184 X509Extension(b('basicConstraints'), True, b('CA:false'))])
Stephen Holsappleca545b72014-01-28 21:43:25 -08001185 exts = request.get_extensions()
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001186 self.assertEqual(len(exts), 1)
1187 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1188 self.assertEqual(exts[0].get_critical(), 1)
1189 self.assertEqual(exts[0].get_data(), b('0\x00'))
1190
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001191 def test_get_extensions(self):
1192 """
1193 :py:obj:`X509Req.get_extensions` returns a :py:obj:`list` of
1194 extensions added to this X509 request.
1195 """
1196 request = X509Req()
1197 exts = request.get_extensions()
1198 self.assertEqual(exts, [])
1199 request.add_extensions([
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001200 X509Extension(b('basicConstraints'), True, b('CA:true')),
1201 X509Extension(b('keyUsage'), False, b('digitalSignature'))])
Stephen Holsapple7fbdf642014-03-01 20:05:47 -08001202 exts = request.get_extensions()
1203 self.assertEqual(len(exts), 2)
1204 self.assertEqual(exts[0].get_short_name(), b('basicConstraints'))
1205 self.assertEqual(exts[0].get_critical(), 1)
1206 self.assertEqual(exts[0].get_data(), b('0\x03\x01\x01\xff'))
1207 self.assertEqual(exts[1].get_short_name(), b('keyUsage'))
1208 self.assertEqual(exts[1].get_critical(), 0)
1209 self.assertEqual(exts[1].get_data(), b('\x03\x02\x07\x80'))
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001210
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001211 def test_add_extensions_wrong_args(self):
1212 """
Alex Gaynor31287502015-09-05 16:11:27 -04001213 :py:obj:`X509Req.add_extensions` raises :py:obj:`TypeError` if called
1214 with the wrong number of arguments or with a non-:py:obj:`list`. Or it
1215 raises :py:obj:`ValueError` if called with a :py:obj:`list` containing
1216 objects other than :py:obj:`X509Extension` instances.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001217 """
1218 request = X509Req()
1219 self.assertRaises(TypeError, request.add_extensions)
1220 self.assertRaises(TypeError, request.add_extensions, object())
1221 self.assertRaises(ValueError, request.add_extensions, [object()])
1222 self.assertRaises(TypeError, request.add_extensions, [], None)
1223
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001224 def test_verify_wrong_args(self):
1225 """
1226 :py:obj:`X509Req.verify` raises :py:obj:`TypeError` if called with zero
1227 arguments or more than one argument or if passed anything other than a
1228 :py:obj:`PKey` instance as its single argument.
1229 """
1230 request = X509Req()
1231 self.assertRaises(TypeError, request.verify)
1232 self.assertRaises(TypeError, request.verify, object())
1233 self.assertRaises(TypeError, request.verify, PKey(), object())
1234
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001235 def test_verify_uninitialized_key(self):
1236 """
Alex Gaynor31287502015-09-05 16:11:27 -04001237 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1238 called with a :py:obj:`OpenSSL.crypto.PKey` which contains no key data.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001239 """
1240 request = X509Req()
1241 pkey = PKey()
1242 self.assertRaises(Error, request.verify, pkey)
1243
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001244 def test_verify_wrong_key(self):
1245 """
Alex Gaynor31287502015-09-05 16:11:27 -04001246 :py:obj:`X509Req.verify` raises :py:obj:`OpenSSL.crypto.Error` if
1247 called with a :py:obj:`OpenSSL.crypto.PKey` which does not represent
1248 the public part of the key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001249 """
1250 request = X509Req()
1251 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001252 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001253 another_pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1254 self.assertRaises(Error, request.verify, another_pkey)
1255
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001256 def test_verify_success(self):
1257 """
1258 :py:obj:`X509Req.verify` returns :py:obj:`True` if called with a
Alex Gaynor31287502015-09-05 16:11:27 -04001259 :py:obj:`OpenSSL.crypto.PKey` which represents the public part of the
1260 key which signed the request.
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001261 """
1262 request = X509Req()
1263 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001264 request.sign(pkey, GOOD_DIGEST)
Jean-Paul Calderone5565f0f2013-03-06 11:10:20 -08001265 self.assertEqual(True, request.verify(pkey))
1266
1267
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001268class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001269 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001270 Tests for :py:obj:`OpenSSL.crypto.X509`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001271 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -04001272 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001273
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001274 extpem = """
1275-----BEGIN CERTIFICATE-----
1276MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
1277BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
1278eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
1279MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
1280aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
1281hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
1282Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
1283zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
1284hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
1285TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
128603HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
1287MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
1288b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
1289MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
1290uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
1291WpOdIpB8KksUTCzV591Nr1wd
1292-----END CERTIFICATE-----
1293 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001294
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001295 def signable(self):
1296 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001297 Create and return a new :py:obj:`X509`.
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -04001298 """
1299 return X509()
1300
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001301 def test_type(self):
1302 """
Alex Gaynor31287502015-09-05 16:11:27 -04001303 :py:obj:`X509` and :py:obj:`X509Type` refer to the same type object and
1304 can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001305 """
1306 self.assertIdentical(X509, X509Type)
1307 self.assertConsistentType(X509, 'X509')
1308
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001309 def test_construction(self):
1310 """
Alex Gaynor31287502015-09-05 16:11:27 -04001311 :py:obj:`X509` takes no arguments and returns an instance of
1312 :py:obj:`X509Type`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001313 """
1314 certificate = X509()
1315 self.assertTrue(
1316 isinstance(certificate, X509Type),
1317 "%r is of type %r, should be %r" % (certificate,
1318 type(certificate),
1319 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -05001320 self.assertEqual(type(X509Type).__name__, 'type')
1321 self.assertEqual(type(certificate).__name__, 'X509')
1322 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -05001323 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001324
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001325 def test_get_version_wrong_args(self):
1326 """
Alex Gaynor31287502015-09-05 16:11:27 -04001327 :py:obj:`X509.get_version` raises :py:obj:`TypeError` if invoked with
1328 any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001329 """
1330 cert = X509()
1331 self.assertRaises(TypeError, cert.get_version, None)
1332
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001333 def test_set_version_wrong_args(self):
1334 """
Alex Gaynor31287502015-09-05 16:11:27 -04001335 :py:obj:`X509.set_version` raises :py:obj:`TypeError` if invoked with
1336 the wrong number of arguments or an argument not of type :py:obj:`int`.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001337 """
1338 cert = X509()
1339 self.assertRaises(TypeError, cert.set_version)
1340 self.assertRaises(TypeError, cert.set_version, None)
1341 self.assertRaises(TypeError, cert.set_version, 1, None)
1342
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001343 def test_version(self):
1344 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001345 :py:obj:`X509.set_version` sets the certificate version number.
1346 :py:obj:`X509.get_version` retrieves it.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001347 """
1348 cert = X509()
1349 cert.set_version(1234)
1350 self.assertEquals(cert.get_version(), 1234)
1351
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001352 def test_get_serial_number_wrong_args(self):
1353 """
Alex Gaynor31287502015-09-05 16:11:27 -04001354 :py:obj:`X509.get_serial_number` raises :py:obj:`TypeError` if invoked
1355 with any arguments.
Jean-Paul Calderone3544eb42010-07-30 22:09:47 -04001356 """
1357 cert = X509()
1358 self.assertRaises(TypeError, cert.get_serial_number, None)
1359
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001360 def test_serial_number(self):
1361 """
Alex Gaynor31287502015-09-05 16:11:27 -04001362 The serial number of an :py:obj:`X509Type` can be retrieved and
1363 modified with :py:obj:`X509Type.get_serial_number` and
1364 :py:obj:`X509Type.set_serial_number`.
Jean-Paul Calderone78381d22008-03-06 23:35:22 -05001365 """
1366 certificate = X509()
1367 self.assertRaises(TypeError, certificate.set_serial_number)
1368 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1369 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1370 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1371 self.assertEqual(certificate.get_serial_number(), 0)
1372 certificate.set_serial_number(1)
1373 self.assertEqual(certificate.get_serial_number(), 1)
1374 certificate.set_serial_number(2 ** 32 + 1)
1375 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1376 certificate.set_serial_number(2 ** 64 + 1)
1377 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001378 certificate.set_serial_number(2 ** 128 + 1)
1379 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1380
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001381 def _setBoundTest(self, which):
1382 """
Alex Gaynor31287502015-09-05 16:11:27 -04001383 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1384 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1385 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001386 """
1387 certificate = X509()
1388 set = getattr(certificate, 'set_not' + which)
1389 get = getattr(certificate, 'get_not' + which)
1390
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -04001391 # Starts with no value.
1392 self.assertEqual(get(), None)
1393
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001394 # GMT (Or is it UTC?) -exarkun
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001395 when = b("20040203040506Z")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001396 set(when)
1397 self.assertEqual(get(), when)
1398
1399 # A plus two hours and thirty minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001400 when = b("20040203040506+0530")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001401 set(when)
1402 self.assertEqual(get(), when)
1403
1404 # A minus one hour fifteen minutes offset
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001405 when = b("20040203040506-0115")
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001406 set(when)
1407 self.assertEqual(get(), when)
1408
1409 # An invalid string results in a ValueError
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001410 self.assertRaises(ValueError, set, b("foo bar"))
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001411
Jean-Paul Calderone31ca2002010-01-30 15:14:43 -05001412 # The wrong number of arguments results in a TypeError.
1413 self.assertRaises(TypeError, set)
Alex Gaynor85b49702015-09-05 16:30:59 -04001414 with pytest.raises(TypeError):
1415 set(b"20040203040506Z", b"20040203040506Z")
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001416 self.assertRaises(TypeError, get, b("foo bar"))
1417
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001418 # XXX ASN1_TIME (not GENERALIZEDTIME)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001419
1420 def test_set_notBefore(self):
1421 """
Alex Gaynor31287502015-09-05 16:11:27 -04001422 :py:obj:`X509Type.set_notBefore` takes a string in the format of an
1423 ASN1 GENERALIZEDTIME and sets the beginning of the certificate's
1424 validity period to it.
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001425 """
1426 self._setBoundTest("Before")
1427
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001428 def test_set_notAfter(self):
1429 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001430 :py:obj:`X509Type.set_notAfter` takes a string in the format of an ASN1
Jean-Paul Calderone525ef802008-03-09 20:39:42 -04001431 GENERALIZEDTIME and sets the end of the certificate's validity period
1432 to it.
1433 """
1434 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -04001435
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001436 def test_get_notBefore(self):
1437 """
Alex Gaynor31287502015-09-05 16:11:27 -04001438 :py:obj:`X509Type.get_notBefore` returns a string in the format of an
1439 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001440 internally.
1441 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -04001442 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001443 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001444
Rick Dean38a05c82009-07-18 01:41:30 -05001445 def test_get_notAfter(self):
1446 """
Alex Gaynor31287502015-09-05 16:11:27 -04001447 :py:obj:`X509Type.get_notAfter` returns a string in the format of an
1448 ASN1 GENERALIZEDTIME even for certificates which store it as UTCTIME
Rick Dean38a05c82009-07-18 01:41:30 -05001449 internally.
1450 """
1451 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderonee890db32010-08-22 16:55:15 -04001452 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
Rick Dean38a05c82009-07-18 01:41:30 -05001453
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001454 def test_gmtime_adj_notBefore_wrong_args(self):
1455 """
Alex Gaynor31287502015-09-05 16:11:27 -04001456 :py:obj:`X509Type.gmtime_adj_notBefore` raises :py:obj:`TypeError` if
1457 called with the wrong number of arguments or a non-:py:obj:`int`
1458 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001459 """
1460 cert = X509()
1461 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1462 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1463 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1464
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001465 def test_gmtime_adj_notBefore(self):
1466 """
Alex Gaynor31287502015-09-05 16:11:27 -04001467 :py:obj:`X509Type.gmtime_adj_notBefore` changes the not-before
1468 timestamp to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001469 """
1470 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001471 not_before_min = (
1472 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1473 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001474 cert.gmtime_adj_notBefore(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001475 not_before = datetime.strptime(
1476 cert.get_notBefore().decode(), "%Y%m%d%H%M%SZ"
1477 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001478 not_before_max = datetime.utcnow() + timedelta(seconds=100)
1479 self.assertTrue(not_before_min <= not_before <= not_before_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001480
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001481 def test_gmtime_adj_notAfter_wrong_args(self):
1482 """
Alex Gaynor31287502015-09-05 16:11:27 -04001483 :py:obj:`X509Type.gmtime_adj_notAfter` raises :py:obj:`TypeError` if
1484 called with the wrong number of arguments or a non-:py:obj:`int`
1485 argument.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001486 """
1487 cert = X509()
1488 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1489 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1490 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1491
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001492 def test_gmtime_adj_notAfter(self):
1493 """
Alex Gaynor31287502015-09-05 16:11:27 -04001494 :py:obj:`X509Type.gmtime_adj_notAfter` changes the not-after timestamp
1495 to be the current time plus the number of seconds passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001496 """
1497 cert = load_certificate(FILETYPE_PEM, self.pemData)
Alex Gaynor85b49702015-09-05 16:30:59 -04001498 not_after_min = (
1499 datetime.utcnow().replace(microsecond=0) + timedelta(seconds=100)
1500 )
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001501 cert.gmtime_adj_notAfter(100)
Alex Gaynor85b49702015-09-05 16:30:59 -04001502 not_after = datetime.strptime(
1503 cert.get_notAfter().decode(), "%Y%m%d%H%M%SZ"
1504 )
Maximilian Hilsbed25c92015-07-25 12:58:07 +02001505 not_after_max = datetime.utcnow() + timedelta(seconds=100)
1506 self.assertTrue(not_after_min <= not_after <= not_after_max)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001507
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001508 def test_has_expired_wrong_args(self):
1509 """
Alex Gaynor31287502015-09-05 16:11:27 -04001510 :py:obj:`X509Type.has_expired` raises :py:obj:`TypeError` if called
1511 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001512 """
1513 cert = X509()
1514 self.assertRaises(TypeError, cert.has_expired, None)
1515
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001516 def test_has_expired(self):
1517 """
Alex Gaynor31287502015-09-05 16:11:27 -04001518 :py:obj:`X509Type.has_expired` returns :py:obj:`True` if the
1519 certificate's not-after time is in the past.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001520 """
1521 cert = X509()
1522 cert.gmtime_adj_notAfter(-1)
1523 self.assertTrue(cert.has_expired())
1524
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001525 def test_has_not_expired(self):
1526 """
Alex Gaynor31287502015-09-05 16:11:27 -04001527 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1528 certificate's not-after time is in the future.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001529 """
1530 cert = X509()
1531 cert.gmtime_adj_notAfter(2)
1532 self.assertFalse(cert.has_expired())
1533
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001534 def test_root_has_not_expired(self):
1535 """
Alex Gaynor31287502015-09-05 16:11:27 -04001536 :py:obj:`X509Type.has_expired` returns :py:obj:`False` if the
1537 certificate's not-after time is in the future.
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001538 """
1539 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1540 self.assertFalse(cert.has_expired())
1541
Rick Dean38a05c82009-07-18 01:41:30 -05001542 def test_digest(self):
1543 """
Alex Gaynor31287502015-09-05 16:11:27 -04001544 :py:obj:`X509.digest` returns a string giving ":"-separated hex-encoded
1545 words of the digest of the certificate.
Rick Dean38a05c82009-07-18 01:41:30 -05001546 """
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001547 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Dean38a05c82009-07-18 01:41:30 -05001548 self.assertEqual(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001549 # This is MD5 instead of GOOD_DIGEST because the digest algorithm
1550 # actually matters to the assertion (ie, another arbitrary, good
1551 # digest will not product the same digest).
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001552 # Digest verified with the command:
1553 # openssl x509 -in root_cert.pem -noout -fingerprint -md5
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001554 cert.digest("MD5"),
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001555 b("19:B3:05:26:2B:F8:F2:FF:0B:8F:21:07:A8:28:B8:75"))
Rick Dean38a05c82009-07-18 01:41:30 -05001556
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001557 def _extcert(self, pkey, extensions):
1558 cert = X509()
1559 cert.set_pubkey(pkey)
1560 cert.get_subject().commonName = "Unit Tests"
1561 cert.get_issuer().commonName = "Unit Tests"
1562 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1563 cert.set_notBefore(when)
1564 cert.set_notAfter(when)
1565
1566 cert.add_extensions(extensions)
Jeff Tangfc18f7b2015-04-15 17:42:33 -04001567 cert.sign(pkey, 'sha1')
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001568 return load_certificate(
1569 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1570
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001571 def test_extension_count(self):
1572 """
Alex Gaynor31287502015-09-05 16:11:27 -04001573 :py:obj:`X509.get_extension_count` returns the number of extensions
1574 that are present in the certificate.
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001575 """
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001576 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001577 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1578 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001579 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001580 b('subjectAltName'), True, b('DNS:example.com'))
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001581
1582 # Try a certificate with no extensions at all.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001583 c = self._extcert(pkey, [])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001584 self.assertEqual(c.get_extension_count(), 0)
1585
1586 # And a certificate with one
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001587 c = self._extcert(pkey, [ca])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001588 self.assertEqual(c.get_extension_count(), 1)
1589
1590 # And a certificate with several
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001591 c = self._extcert(pkey, [ca, key, subjectAltName])
Jean-Paul Calderonef7b3ee62011-04-01 17:36:24 -04001592 self.assertEqual(c.get_extension_count(), 3)
Roland Hedberg7e4930e2008-04-22 22:58:50 +02001593
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001594 def test_get_extension(self):
1595 """
Alex Gaynor31287502015-09-05 16:11:27 -04001596 :py:obj:`X509.get_extension` takes an integer and returns an
1597 :py:obj:`X509Extension` corresponding to the extension at that index.
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001598 """
1599 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001600 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1601 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001602 subjectAltName = X509Extension(
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001603 b('subjectAltName'), False, b('DNS:example.com'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001604
1605 cert = self._extcert(pkey, [ca, key, subjectAltName])
1606
1607 ext = cert.get_extension(0)
1608 self.assertTrue(isinstance(ext, X509Extension))
1609 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001610 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001611
1612 ext = cert.get_extension(1)
1613 self.assertTrue(isinstance(ext, X509Extension))
1614 self.assertTrue(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001615 self.assertEqual(ext.get_short_name(), b('keyUsage'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001616
1617 ext = cert.get_extension(2)
1618 self.assertTrue(isinstance(ext, X509Extension))
1619 self.assertFalse(ext.get_critical())
Jean-Paul Calderone90abbc02011-04-06 18:20:22 -04001620 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone83a593d2011-04-01 17:45:07 -04001621
1622 self.assertRaises(IndexError, cert.get_extension, -1)
1623 self.assertRaises(IndexError, cert.get_extension, 4)
1624 self.assertRaises(TypeError, cert.get_extension, "hello")
1625
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001626 def test_nullbyte_subjectAltName(self):
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001627 """
Jean-Paul Calderone9af07b02013-08-23 16:07:31 -04001628 The fields of a `subjectAltName` extension on an X509 may contain NUL
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001629 bytes and this value is reflected in the string representation of the
1630 extension object.
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001631 """
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001632 cert = load_certificate(FILETYPE_PEM, nulbyteSubjectAltNamePEM)
Jean-Paul Calderoneff83cdd2013-08-12 18:05:51 -04001633
1634 ext = cert.get_extension(3)
1635 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
Jean-Paul Calderone4bf75c62013-08-23 15:39:53 -04001636 self.assertEqual(
1637 b("DNS:altnull.python.org\x00example.com, "
1638 "email:null@python.org\x00user@example.org, "
1639 "URI:http://null.python.org\x00http://example.org, "
1640 "IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1\n"),
1641 b(str(ext)))
1642
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001643 def test_invalid_digest_algorithm(self):
1644 """
Alex Gaynor31287502015-09-05 16:11:27 -04001645 :py:obj:`X509.digest` raises :py:obj:`ValueError` if called with an
1646 unrecognized hash algorithm.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001647 """
1648 cert = X509()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001649 self.assertRaises(ValueError, cert.digest, BAD_DIGEST)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04001650
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001651 def test_get_subject_wrong_args(self):
1652 """
Alex Gaynor31287502015-09-05 16:11:27 -04001653 :py:obj:`X509.get_subject` raises :py:obj:`TypeError` if called with
1654 any arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001655 """
1656 cert = X509()
1657 self.assertRaises(TypeError, cert.get_subject, None)
1658
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001659 def test_get_subject(self):
1660 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001661 :py:obj:`X509.get_subject` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001662 """
1663 cert = load_certificate(FILETYPE_PEM, self.pemData)
1664 subj = cert.get_subject()
1665 self.assertTrue(isinstance(subj, X509Name))
1666 self.assertEquals(
1667 subj.get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001668 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1669 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001670
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001671 def test_set_subject_wrong_args(self):
1672 """
Alex Gaynor31287502015-09-05 16:11:27 -04001673 :py:obj:`X509.set_subject` raises a :py:obj:`TypeError` if called with
1674 the wrong number of arguments or an argument not of type
1675 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001676 """
1677 cert = X509()
1678 self.assertRaises(TypeError, cert.set_subject)
1679 self.assertRaises(TypeError, cert.set_subject, None)
Alex Gaynor85b49702015-09-05 16:30:59 -04001680 with pytest.raises(TypeError):
1681 cert.set_subject(cert.get_subject(), None)
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001682
1683 def test_set_subject(self):
1684 """
Alex Gaynor31287502015-09-05 16:11:27 -04001685 :py:obj:`X509.set_subject` changes the subject of the certificate to
1686 the one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001687 """
1688 cert = X509()
1689 name = cert.get_subject()
1690 name.C = 'AU'
1691 name.O = 'Unit Tests'
1692 cert.set_subject(name)
1693 self.assertEquals(
1694 cert.get_subject().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001695 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001696
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001697 def test_get_issuer_wrong_args(self):
1698 """
Alex Gaynor31287502015-09-05 16:11:27 -04001699 :py:obj:`X509.get_issuer` raises :py:obj:`TypeError` if called with any
1700 arguments.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001701 """
1702 cert = X509()
1703 self.assertRaises(TypeError, cert.get_issuer, None)
1704
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001705 def test_get_issuer(self):
1706 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001707 :py:obj:`X509.get_issuer` returns an :py:obj:`X509Name` instance.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001708 """
1709 cert = load_certificate(FILETYPE_PEM, self.pemData)
1710 subj = cert.get_issuer()
1711 self.assertTrue(isinstance(subj, X509Name))
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001712 comp = subj.get_components()
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001713 self.assertEquals(
Jean-Paul Calderone30a4cb32010-08-11 23:54:12 -04001714 comp,
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001715 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1716 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001717
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001718 def test_set_issuer_wrong_args(self):
1719 """
Alex Gaynor31287502015-09-05 16:11:27 -04001720 :py:obj:`X509.set_issuer` raises a :py:obj:`TypeError` if called with
1721 the wrong number of arguments or an argument not of type
1722 :py:obj:`X509Name`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001723 """
1724 cert = X509()
1725 self.assertRaises(TypeError, cert.set_issuer)
1726 self.assertRaises(TypeError, cert.set_issuer, None)
1727 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1728
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001729 def test_set_issuer(self):
1730 """
Alex Gaynor31287502015-09-05 16:11:27 -04001731 :py:obj:`X509.set_issuer` changes the issuer of the certificate to the
1732 one passed in.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001733 """
1734 cert = X509()
1735 name = cert.get_issuer()
1736 name.C = 'AU'
1737 name.O = 'Unit Tests'
1738 cert.set_issuer(name)
1739 self.assertEquals(
1740 cert.get_issuer().get_components(),
Jean-Paul Calderonedc3275f2010-08-22 17:04:09 -04001741 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001742
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001743 def test_get_pubkey_uninitialized(self):
1744 """
Alex Gaynor31287502015-09-05 16:11:27 -04001745 When called on a certificate with no public key,
1746 :py:obj:`X509.get_pubkey` raises :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone4f237b22010-07-30 22:29:39 -04001747 """
1748 cert = X509()
1749 self.assertRaises(Error, cert.get_pubkey)
1750
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001751 def test_subject_name_hash_wrong_args(self):
1752 """
Alex Gaynor31287502015-09-05 16:11:27 -04001753 :py:obj:`X509.subject_name_hash` raises :py:obj:`TypeError` if called
1754 with any arguments.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001755 """
1756 cert = X509()
1757 self.assertRaises(TypeError, cert.subject_name_hash, None)
1758
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001759 def test_subject_name_hash(self):
1760 """
Alex Gaynor31287502015-09-05 16:11:27 -04001761 :py:obj:`X509.subject_name_hash` returns the hash of the certificate's
1762 subject name.
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001763 """
1764 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001765 self.assertIn(
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001766 cert.subject_name_hash(),
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001767 [3350047874, # OpenSSL 0.9.8, MD5
1768 3278919224, # OpenSSL 1.0.0, SHA1
Jean-Paul Calderone060a57e2011-05-04 18:02:49 -04001769 ])
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001770
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001771 def test_get_signature_algorithm(self):
1772 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001773 :py:obj:`X509Type.get_signature_algorithm` returns a string which means
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001774 the algorithm used to sign the certificate.
1775 """
1776 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001777 self.assertEqual(
1778 b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001779
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001780 def test_get_undefined_signature_algorithm(self):
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001781 """
Alex Gaynor31287502015-09-05 16:11:27 -04001782 :py:obj:`X509Type.get_signature_algorithm` raises :py:obj:`ValueError`
1783 if the signature algorithm is undefined or unknown.
Jean-Paul Calderone5d8e4052011-05-19 17:51:43 -04001784 """
1785 # This certificate has been modified to indicate a bogus OID in the
1786 # signature algorithm field so that OpenSSL does not recognize it.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001787 certPEM = b("""\
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001788-----BEGIN CERTIFICATE-----
1789MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
1790EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
1791cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
1792MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
1793EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
1794CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
1795AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
1796+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
1797hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
1798BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
1799FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
1800dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
1801aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
1802MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
1803jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
1804PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
1805tgI5
1806-----END CERTIFICATE-----
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001807""")
Jean-Paul Calderone2755fa52011-05-18 19:42:10 -04001808 cert = load_certificate(FILETYPE_PEM, certPEM)
1809 self.assertRaises(ValueError, cert.get_signature_algorithm)
Jean-Paul Calderoneccf9d482010-07-30 22:36:42 -04001810
1811
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001812class X509StoreTests(TestCase):
1813 """
1814 Test for :py:obj:`OpenSSL.crypto.X509Store`.
1815 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04001816
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001817 def test_type(self):
1818 """
1819 :py:obj:`X509StoreType` is a type object.
1820 """
1821 self.assertIdentical(X509Store, X509StoreType)
1822 self.assertConsistentType(X509Store, 'X509Store')
1823
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001824 def test_add_cert_wrong_args(self):
1825 store = X509Store()
1826 self.assertRaises(TypeError, store.add_cert)
1827 self.assertRaises(TypeError, store.add_cert, object())
1828 self.assertRaises(TypeError, store.add_cert, X509(), object())
1829
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001830 def test_add_cert(self):
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001831 """
1832 :py:obj:`X509Store.add_cert` adds a :py:obj:`X509` instance to the
1833 certificate store.
1834 """
1835 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001836 store = X509Store()
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001837 store.add_cert(cert)
1838
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001839 def test_add_cert_rejects_duplicate(self):
1840 """
Alex Gaynor31287502015-09-05 16:11:27 -04001841 :py:obj:`X509Store.add_cert` raises :py:obj:`OpenSSL.crypto.Error` if
1842 an attempt is made to add the same certificate to the store more than
1843 once.
Jean-Paul Calderonee6f32b82013-03-06 10:27:57 -08001844 """
1845 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1846 store = X509Store()
1847 store.add_cert(cert)
1848 self.assertRaises(Error, store.add_cert, cert)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001849
1850
Rick Dean623ee362009-07-17 12:22:16 -05001851class PKCS12Tests(TestCase):
1852 """
Alex Gaynor31287502015-09-05 16:11:27 -04001853 Test for :py:obj:`OpenSSL.crypto.PKCS12` and
1854 :py:obj:`OpenSSL.crypto.load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001855 """
1856 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1857
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001858 def test_type(self):
1859 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001860 :py:obj:`PKCS12Type` is a type object.
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -04001861 """
1862 self.assertIdentical(PKCS12, PKCS12Type)
1863 self.assertConsistentType(PKCS12, 'PKCS12')
1864
Rick Deanf94096c2009-07-18 14:23:06 -05001865 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001866 """
Alex Gaynor31287502015-09-05 16:11:27 -04001867 :py:obj:`PKCS12` returns a new instance of :py:obj:`PKCS12` with no
1868 certificate, private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -05001869 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001870 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001871 self.assertEqual(None, p12.get_certificate())
1872 self.assertEqual(None, p12.get_privatekey())
1873 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -05001874 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -05001875
1876 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -05001877 """
Alex Gaynor31287502015-09-05 16:11:27 -04001878 The :py:obj:`PKCS12` setter functions (:py:obj:`set_certificate`,
1879 :py:obj:`set_privatekey`, :py:obj:`set_ca_certificates`, and
1880 :py:obj:`set_friendlyname`) raise :py:obj:`TypeError` when passed
1881 objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001882 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001883 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001884 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001885 self.assertRaises(TypeError, p12.set_certificate, PKey())
1886 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001887 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001888 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1889 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001890 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1891 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1892 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Alex Gaynor7f636492015-09-04 13:26:52 -04001893 self.assertRaises(TypeError, p12.set_ca_certificates, (PKey(),))
Rick Dean42d69e12009-07-20 11:36:08 -05001894 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1895 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001896
1897 def test_key_only(self):
1898 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001899 A :py:obj:`PKCS12` with only a private key can be exported using
1900 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001901 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001902 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001903 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001904 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001905 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05001906 self.assertEqual(None, p12.get_certificate())
1907 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001908 try:
1909 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1910 except Error:
1911 # Some versions of OpenSSL will throw an exception
1912 # for this nearly useless PKCS12 we tried to generate:
1913 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1914 return
Rick Dean623ee362009-07-17 12:22:16 -05001915 p12 = load_pkcs12(dumped_p12, passwd)
1916 self.assertEqual(None, p12.get_ca_certificates())
1917 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001918
1919 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1920 # future this will be improved.
1921 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05001922
1923 def test_cert_only(self):
1924 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001925 A :py:obj:`PKCS12` with only a certificate can be exported using
1926 :py:obj:`PKCS12.export` and loaded again using :py:obj:`load_pkcs12`.
Rick Dean623ee362009-07-17 12:22:16 -05001927 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001928 passwd = b"blah"
Rick Dean623ee362009-07-17 12:22:16 -05001929 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001930 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001931 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05001932 self.assertEqual(cert, p12.get_certificate())
1933 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001934 try:
1935 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1936 except Error:
1937 # Some versions of OpenSSL will throw an exception
1938 # for this nearly useless PKCS12 we tried to generate:
1939 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1940 return
Rick Dean623ee362009-07-17 12:22:16 -05001941 p12 = load_pkcs12(dumped_p12, passwd)
1942 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001943
1944 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
1945 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1946
1947 # Oh ho. It puts the certificate into the ca certificates list, in
1948 # fact. Totally bogus, I would think. Nevertheless, let's exploit
1949 # that to check to see if it reconstructed the certificate we expected
1950 # it to. At some point, hopefully this will change so that
1951 # p12.get_certificate() is actually what returns the loaded
1952 # certificate.
1953 self.assertEqual(
1954 cleartextCertificatePEM,
1955 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05001956
Alex Gaynor31287502015-09-05 16:11:27 -04001957 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None,
1958 friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05001959 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001960 Generate a PKCS12 object with components from PEM. Verify that the set
1961 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05001962 """
Rick Deanf94096c2009-07-18 14:23:06 -05001963 p12 = PKCS12()
1964 if cert_pem:
1965 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1966 self.assertEqual(ret, None)
1967 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001968 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05001969 self.assertEqual(ret, None)
1970 if ca_pem:
Alex Gaynor85b49702015-09-05 16:30:59 -04001971 ret = p12.set_ca_certificates(
1972 (load_certificate(FILETYPE_PEM, ca_pem),)
1973 )
Rick Deanf94096c2009-07-18 14:23:06 -05001974 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001975 if friendly_name:
1976 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05001977 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05001978 return p12
1979
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001980 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd=b"",
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001981 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05001982 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001983 Use openssl program to confirm three components are recoverable from a
1984 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05001985 """
1986 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001987 recovered_key = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001988 p12_str, b"pkcs12", b"-nocerts", b"-nodes", b"-passin",
1989 b"pass:" + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001990 self.assertEqual(recovered_key[-len(key):], key)
1991 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001992 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001993 p12_str, b"pkcs12", b"-clcerts", b"-nodes", b"-passin",
1994 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001995 self.assertEqual(recovered_cert[-len(cert):], cert)
1996 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001997 recovered_cert = _runopenssl(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001998 p12_str, b"pkcs12", b"-cacerts", b"-nodes", b"-passin",
1999 b"pass:" + passwd, b"-nokeys", *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05002000 self.assertEqual(recovered_cert[-len(ca):], ca)
2001
Stephen Holsapple38482622014-04-05 20:29:34 -07002002 def verify_pkcs12_container(self, p12):
2003 """
2004 Verify that the PKCS#12 container contains the correct client
2005 certificate and private key.
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002006
2007 :param p12: The PKCS12 instance to verify.
2008 :type p12: :py:class:`PKCS12`
Stephen Holsapple38482622014-04-05 20:29:34 -07002009 """
2010 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
2011 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002012 self.assertEqual(
2013 (client_cert_pem, client_key_pem, None),
2014 (cert_pem, key_pem, p12.get_ca_certificates()))
Stephen Holsapple38482622014-04-05 20:29:34 -07002015
Rick Deanf94096c2009-07-18 14:23:06 -05002016 def test_load_pkcs12(self):
2017 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002018 A PKCS12 string generated using the openssl command line can be loaded
Jonathan Ballet648875f2011-07-16 14:14:58 +09002019 with :py:obj:`load_pkcs12` and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05002020 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002021 passwd = b"whatever"
Rick Dean623ee362009-07-17 12:22:16 -05002022 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002023 p12_str = _runopenssl(
Alex Gaynor85b49702015-09-05 16:30:59 -04002024 pem,
2025 b"pkcs12",
2026 b"-export",
2027 b"-clcerts",
2028 b"-passout",
2029 b"pass:" + passwd
2030 )
Stephen Holsapple38482622014-04-05 20:29:34 -07002031 p12 = load_pkcs12(p12_str, passphrase=passwd)
2032 self.verify_pkcs12_container(p12)
2033
Abraham Martinc5484ba2015-03-25 15:33:05 +00002034 def test_load_pkcs12_text_passphrase(self):
2035 """
2036 A PKCS12 string generated using the openssl command line can be loaded
2037 with :py:obj:`load_pkcs12` and its components extracted and examined.
2038 Using text as passphrase instead of bytes. DeprecationWarning expected.
2039 """
2040 pem = client_key_pem + client_cert_pem
2041 passwd = b"whatever"
2042 p12_str = _runopenssl(pem, b"pkcs12", b"-export", b"-clcerts",
2043 b"-passout", b"pass:" + passwd)
2044 with catch_warnings(record=True) as w:
2045 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002046 p12 = load_pkcs12(p12_str, passphrase=b"whatever".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002047
2048 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002049 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002050 WARNING_TYPE_EXPECTED
2051 ),
2052 str(w[-1].message)
2053 )
2054 self.assertIs(w[-1].category, DeprecationWarning)
2055
Abraham Martinc5484ba2015-03-25 15:33:05 +00002056 self.verify_pkcs12_container(p12)
2057
Stephen Holsapple38482622014-04-05 20:29:34 -07002058 def test_load_pkcs12_no_passphrase(self):
2059 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002060 A PKCS12 string generated using openssl command line can be loaded with
2061 :py:obj:`load_pkcs12` without a passphrase and its components extracted
2062 and examined.
Stephen Holsapple38482622014-04-05 20:29:34 -07002063 """
2064 pem = client_key_pem + client_cert_pem
2065 p12_str = _runopenssl(
2066 pem, b"pkcs12", b"-export", b"-clcerts", b"-passout", b"pass:")
2067 p12 = load_pkcs12(p12_str)
2068 self.verify_pkcs12_container(p12)
2069
Stephen Holsapple38482622014-04-05 20:29:34 -07002070 def _dump_and_load(self, dump_passphrase, load_passphrase):
2071 """
2072 A helper method to dump and load a PKCS12 object.
2073 """
2074 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem)
2075 dumped_p12 = p12.export(passphrase=dump_passphrase, iter=2, maciter=3)
2076 return load_pkcs12(dumped_p12, passphrase=load_passphrase)
2077
Stephen Holsapple38482622014-04-05 20:29:34 -07002078 def test_load_pkcs12_null_passphrase_load_empty(self):
2079 """
2080 A PKCS12 string can be dumped with a null passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002081 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002082 extracted and examined.
2083 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002084 self.verify_pkcs12_container(
2085 self._dump_and_load(dump_passphrase=None, load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002086
Stephen Holsapple38482622014-04-05 20:29:34 -07002087 def test_load_pkcs12_null_passphrase_load_null(self):
2088 """
2089 A PKCS12 string can be dumped with a null passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002090 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002091 extracted and examined.
2092 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002093 self.verify_pkcs12_container(
2094 self._dump_and_load(dump_passphrase=None, load_passphrase=None))
Stephen Holsapple38482622014-04-05 20:29:34 -07002095
Stephen Holsapple38482622014-04-05 20:29:34 -07002096 def test_load_pkcs12_empty_passphrase_load_empty(self):
2097 """
2098 A PKCS12 string can be dumped with an empty passphrase, loaded with an
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002099 empty passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002100 extracted and examined.
2101 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002102 self.verify_pkcs12_container(
2103 self._dump_and_load(dump_passphrase=b'', load_passphrase=b''))
Stephen Holsapple38482622014-04-05 20:29:34 -07002104
Stephen Holsapple38482622014-04-05 20:29:34 -07002105 def test_load_pkcs12_empty_passphrase_load_null(self):
2106 """
2107 A PKCS12 string can be dumped with an empty passphrase, loaded with a
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002108 null passphrase with :py:obj:`load_pkcs12`, and its components
Stephen Holsapple38482622014-04-05 20:29:34 -07002109 extracted and examined.
2110 """
Jean-Paul Calderonef0ff13b2014-05-05 12:48:33 -04002111 self.verify_pkcs12_container(
2112 self._dump_and_load(dump_passphrase=b'', load_passphrase=None))
Rick Deanf94096c2009-07-18 14:23:06 -05002113
Rick Deanee568302009-07-24 09:56:29 -05002114 def test_load_pkcs12_garbage(self):
2115 """
Alex Gaynor85b49702015-09-05 16:30:59 -04002116 :py:obj:`load_pkcs12` raises :py:obj:`OpenSSL.crypto.Error` when passed
2117 a string which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05002118 """
2119 passwd = 'whatever'
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002120 e = self.assertRaises(Error, load_pkcs12, b'fruit loops', passwd)
Alex Gaynor7f636492015-09-04 13:26:52 -04002121 self.assertEqual(e.args[0][0][0], 'asn1 encoding routines')
2122 self.assertEqual(len(e.args[0][0]), 3)
Rick Deanee568302009-07-24 09:56:29 -05002123
Rick Deanf94096c2009-07-18 14:23:06 -05002124 def test_replace(self):
2125 """
Alex Gaynor31287502015-09-05 16:11:27 -04002126 :py:obj:`PKCS12.set_certificate` replaces the certificate in a PKCS12
2127 cluster. :py:obj:`PKCS12.set_privatekey` replaces the private key.
Jonathan Ballet648875f2011-07-16 14:14:58 +09002128 :py:obj:`PKCS12.set_ca_certificates` replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002129 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002130 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
2131 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2132 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002133 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002134 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002135 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05002136 self.assertEqual(1, len(p12.get_ca_certificates()))
2137 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002138 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05002139 self.assertEqual(2, len(p12.get_ca_certificates()))
2140 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
2141 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
2142
Rick Deanf94096c2009-07-18 14:23:06 -05002143 def test_friendly_name(self):
2144 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002145 The *friendlyName* of a PKCS12 can be set and retrieved via
Alex Gaynor85b49702015-09-05 16:30:59 -04002146 :py:obj:`PKCS12.get_friendlyname` and
2147 :py:obj:`PKCS12_set_friendlyname`, and a :py:obj:`PKCS12` with a
2148 friendly name set can be dumped with :py:obj:`PKCS12.export`.
Rick Deanf94096c2009-07-18 14:23:06 -05002149 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002150 passwd = b'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002151 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -04002152 for friendly_name in [b('Serverlicious'), None, b('###')]:
Rick Dean42d69e12009-07-20 11:36:08 -05002153 p12.set_friendlyname(friendly_name)
2154 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002155 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05002156 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002157 self.assertEqual(
Jean-Paul Calderone9da338d2011-05-04 11:40:54 -04002158 p12.get_friendlyname(), reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04002159 # We would use the openssl program to confirm the friendly
2160 # name, but it is not possible. The pkcs12 command
2161 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05002162 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002163 self.check_recovery(
2164 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2165 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002166
Rick Deanf94096c2009-07-18 14:23:06 -05002167 def test_various_empty_passphrases(self):
2168 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002169 Test that missing, None, and '' passphrases are identical for PKCS12
2170 export.
Rick Deanf94096c2009-07-18 14:23:06 -05002171 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002172 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002173 passwd = b""
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002174 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
2175 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
2176 dumped_p12_nopw = p12.export(iter=9, maciter=4)
2177 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
2178 self.check_recovery(
2179 dumped_p12, key=client_key_pem, cert=client_cert_pem,
2180 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05002181
Rick Deanf94096c2009-07-18 14:23:06 -05002182 def test_removing_ca_cert(self):
2183 """
Alex Gaynor31287502015-09-05 16:11:27 -04002184 Passing :py:obj:`None` to :py:obj:`PKCS12.set_ca_certificates` removes
2185 all CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05002186 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002187 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2188 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05002189 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05002190
Rick Deanf94096c2009-07-18 14:23:06 -05002191 def test_export_without_mac(self):
2192 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002193 Exporting a PKCS12 with a :py:obj:`maciter` of ``-1`` excludes the MAC
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002194 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05002195 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002196 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002197 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05002198 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002199 self.check_recovery(
2200 dumped_p12, key=server_key_pem, cert=server_cert_pem,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002201 passwd=passwd, extra=(b"-nomacver",))
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002202
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002203 def test_load_without_mac(self):
2204 """
2205 Loading a PKCS12 without a MAC does something other than crash.
2206 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002207 passwd = b"Lake Michigan"
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04002208 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2209 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05002210 try:
2211 recovered_p12 = load_pkcs12(dumped_p12, passwd)
2212 # The person who generated this PCKS12 should be flogged,
2213 # or better yet we should have a means to determine
2214 # whether a PCKS12 had a MAC that was verified.
2215 # Anyway, libopenssl chooses to allow it, so the
2216 # pyopenssl binding does as well.
2217 self.assertTrue(isinstance(recovered_p12, PKCS12))
2218 except Error:
2219 # Failing here with an exception is preferred as some openssl
2220 # versions do.
2221 pass
Rick Dean623ee362009-07-17 12:22:16 -05002222
Rick Dean25bcc1f2009-07-20 11:53:13 -05002223 def test_zero_len_list_for_ca(self):
2224 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002225 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05002226 """
Alex Gaynor6575bd12015-09-05 16:44:36 -04002227 passwd = b'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002228 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
Alex Gaynor85b49702015-09-05 16:30:59 -04002229 p12.set_ca_certificates([])
2230 self.assertEqual((), p12.get_ca_certificates())
2231 dumped_p12 = p12.export(passphrase=passwd, iter=3)
2232 self.check_recovery(
2233 dumped_p12, key=server_key_pem, cert=server_cert_pem,
2234 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05002235
Rick Deanf94096c2009-07-18 14:23:06 -05002236 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002237 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002238 All the arguments to :py:obj:`PKCS12.export` are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04002239 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002240 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05002241 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002242 self.check_recovery(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002243 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd=b"")
Rick Deanf94096c2009-07-18 14:23:06 -05002244
Abraham Martinc5484ba2015-03-25 15:33:05 +00002245 def test_export_without_bytes(self):
2246 """
2247 Test :py:obj:`PKCS12.export` with text not bytes as passphrase
2248 """
2249 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
2250
2251 with catch_warnings(record=True) as w:
2252 simplefilter("always")
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002253 dumped_p12 = p12.export(passphrase=b"randomtext".decode("ascii"))
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002254 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04002255 "{0} for passphrase is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04002256 WARNING_TYPE_EXPECTED
2257 ),
2258 str(w[-1].message)
2259 )
2260 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00002261 self.check_recovery(
Alex Gaynor791212d2015-09-05 15:46:08 -04002262 dumped_p12,
2263 key=server_key_pem,
2264 cert=server_cert_pem,
2265 passwd=b"randomtext"
2266 )
Abraham Martinc5484ba2015-03-25 15:33:05 +00002267
Rick Deanf94096c2009-07-18 14:23:06 -05002268 def test_key_cert_mismatch(self):
2269 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002270 :py:obj:`PKCS12.export` raises an exception when a key and certificate
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002271 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05002272 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04002273 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
2274 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002275
2276
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002277# These quoting functions taken directly from Twisted's twisted.python.win32.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002278_cmdLineQuoteRe = re.compile(br'(\\*)"')
2279_cmdLineQuoteRe2 = re.compile(br'(\\+)\Z')
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002280
2281
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002282def cmdLineQuote(s):
2283 """
2284 Internal method for quoting a single command-line argument.
2285
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002286 See http://www.perlmonks.org/?node_id=764004
2287
Jonathan Ballet648875f2011-07-16 14:14:58 +09002288 :type: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002289 :param s: A single unquoted string to quote for something that is expecting
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002290 cmd.exe-style quoting
2291
Jonathan Ballet648875f2011-07-16 14:14:58 +09002292 :rtype: :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002293 :return: A cmd.exe-style quoted string
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002294 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002295 s = _cmdLineQuoteRe2.sub(br"\1\1", _cmdLineQuoteRe.sub(br'\1\1\\"', s))
2296 return b'"' + s + b'"'
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002297
2298
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002299def quoteArguments(arguments):
2300 """
2301 Quote an iterable of command-line arguments for passing to CreateProcess or
Alex Gaynor791212d2015-09-05 15:46:08 -04002302 a similar API. This allows the list passed to
2303 :py:obj:`reactor.spawnProcess` to match the child process's
2304 :py:obj:`sys.argv` properly.
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002305
Jonathan Ballet648875f2011-07-16 14:14:58 +09002306 :type arguments: :py:obj:`iterable` of :py:obj:`str`
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002307 :param arguments: An iterable of unquoted arguments to quote
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002308
Jonathan Ballet648875f2011-07-16 14:14:58 +09002309 :rtype: :py:obj:`str`
Alex Gaynor791212d2015-09-05 15:46:08 -04002310 :return: A space-delimited string containing quoted versions of
2311 :py:obj:`arguments`
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002312 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002313 return b' '.join(map(cmdLineQuote, arguments))
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04002314
2315
Rick Dean4c9ad612009-07-17 15:05:22 -05002316def _runopenssl(pem, *args):
2317 """
2318 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05002319 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05002320 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04002321 if os.name == 'posix':
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002322 command = b"openssl " + b" ".join([
Alex Gaynor85b49702015-09-05 16:30:59 -04002323 (b"'" + arg.replace(b"'", b"'\\''") + b"'")
2324 for arg in args
2325 ])
Rick Dean55d1ce62009-08-13 17:40:24 -05002326 else:
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002327 command = b"openssl " + quoteArguments(args)
2328 proc = Popen(native(command), shell=True, stdin=PIPE, stdout=PIPE)
Jean-Paul Calderone62ca8da2010-08-11 19:58:08 -04002329 proc.stdin.write(pem)
2330 proc.stdin.close()
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002331 output = proc.stdout.read()
2332 proc.stdout.close()
2333 proc.wait()
2334 return output
Rick Dean4c9ad612009-07-17 15:05:22 -05002335
2336
Jean-Paul Calderone18808652009-07-05 12:54:05 -04002337class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002338 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002339 Tests for free-functions in the :py:obj:`OpenSSL.crypto` module.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002340 """
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002341
2342 def test_load_privatekey_invalid_format(self):
2343 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002344 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if passed an
2345 unknown filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002346 """
2347 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
2348
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002349 def test_load_privatekey_invalid_passphrase_type(self):
2350 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002351 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if passed a
2352 passphrase that is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002353 """
2354 self.assertRaises(
2355 TypeError,
2356 load_privatekey,
2357 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
2358
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002359 def test_load_privatekey_wrong_args(self):
2360 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002361 :py:obj:`load_privatekey` raises :py:obj:`TypeError` if called with the
2362 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002363 """
2364 self.assertRaises(TypeError, load_privatekey)
2365
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002366 def test_load_privatekey_wrongPassphrase(self):
2367 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002368 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2369 is passed an encrypted PEM and an incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002370 """
2371 self.assertRaises(
2372 Error,
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002373 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002374
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002375 def test_load_privatekey_passphraseWrongType(self):
2376 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002377 :py:obj:`load_privatekey` raises :py:obj:`ValueError` when it is passed
2378 a passphrase with a private key encoded in a format, that doesn't
2379 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002380 """
2381 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2382 blob = dump_privatekey(FILETYPE_ASN1, key)
2383 self.assertRaises(ValueError,
Alex Gaynor791212d2015-09-05 15:46:08 -04002384 load_privatekey, FILETYPE_ASN1, blob, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002385
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002386 def test_load_privatekey_passphrase(self):
2387 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002388 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2389 encrypted PEM string if given the passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002390 """
2391 key = load_privatekey(
2392 FILETYPE_PEM, encryptedPrivateKeyPEM,
2393 encryptedPrivateKeyPEMPassphrase)
2394 self.assertTrue(isinstance(key, PKeyType))
2395
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002396 def test_load_privatekey_passphrase_exception(self):
2397 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002398 If the passphrase callback raises an exception, that exception is
2399 raised by :py:obj:`load_privatekey`.
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002400 """
2401 def cb(ignored):
2402 raise ArithmeticError
2403
Alex Gaynor791212d2015-09-05 15:46:08 -04002404 with pytest.raises(ArithmeticError):
2405 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002406
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002407 def test_load_privatekey_wrongPassphraseCallback(self):
2408 """
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002409 :py:obj:`load_privatekey` raises :py:obj:`OpenSSL.crypto.Error` when it
2410 is passed an encrypted PEM and a passphrase callback which returns an
2411 incorrect passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002412 """
2413 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002414
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002415 def cb(*a):
2416 called.append(None)
Jean-Paul Calderoned440a082011-09-14 11:02:05 -04002417 return b("quack")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002418 self.assertRaises(
2419 Error,
2420 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2421 self.assertTrue(called)
2422
2423 def test_load_privatekey_passphraseCallback(self):
2424 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002425 :py:obj:`load_privatekey` can create a :py:obj:`PKey` object from an
2426 encrypted PEM string if given a passphrase callback which returns the
2427 correct password.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002428 """
2429 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002430
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002431 def cb(writing):
2432 called.append(writing)
2433 return encryptedPrivateKeyPEMPassphrase
2434 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
2435 self.assertTrue(isinstance(key, PKeyType))
2436 self.assertEqual(called, [False])
2437
Jean-Paul Calderone105cb952011-09-14 10:16:46 -04002438 def test_load_privatekey_passphrase_wrong_return_type(self):
2439 """
2440 :py:obj:`load_privatekey` raises :py:obj:`ValueError` if the passphrase
2441 callback returns something other than a byte string.
2442 """
2443 self.assertRaises(
2444 ValueError,
2445 load_privatekey,
2446 FILETYPE_PEM, encryptedPrivateKeyPEM, lambda *args: 3)
2447
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002448 def test_dump_privatekey_wrong_args(self):
2449 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002450 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with the
2451 wrong number of arguments.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002452 """
2453 self.assertRaises(TypeError, dump_privatekey)
Jean-Paul Calderone1eeccd82011-09-14 10:18:52 -04002454 # If cipher name is given, password is required.
2455 self.assertRaises(
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002456 TypeError, dump_privatekey, FILETYPE_PEM, PKey(), GOOD_CIPHER)
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002457
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002458 def test_dump_privatekey_unknown_cipher(self):
2459 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002460 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2461 unrecognized cipher name.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002462 """
2463 key = PKey()
2464 key.generate_key(TYPE_RSA, 512)
2465 self.assertRaises(
2466 ValueError, dump_privatekey,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002467 FILETYPE_PEM, key, BAD_CIPHER, "passphrase")
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002468
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002469 def test_dump_privatekey_invalid_passphrase_type(self):
2470 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002471 :py:obj:`dump_privatekey` raises :py:obj:`TypeError` if called with a
2472 passphrase which is neither a :py:obj:`str` nor a callable.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002473 """
2474 key = PKey()
2475 key.generate_key(TYPE_RSA, 512)
2476 self.assertRaises(
2477 TypeError,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002478 dump_privatekey, FILETYPE_PEM, key, GOOD_CIPHER, object())
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002479
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002480 def test_dump_privatekey_invalid_filetype(self):
2481 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002482 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` if called with an
2483 unrecognized filetype.
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002484 """
2485 key = PKey()
2486 key.generate_key(TYPE_RSA, 512)
2487 self.assertRaises(ValueError, dump_privatekey, 100, key)
2488
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002489 def test_load_privatekey_passphraseCallbackLength(self):
2490 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002491 :py:obj:`crypto.load_privatekey` should raise an error when the
2492 passphrase provided by the callback is too long, not silently truncate
2493 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002494 """
2495 def cb(ignored):
2496 return "a" * 1025
2497
Alex Gaynor791212d2015-09-05 15:46:08 -04002498 with pytest.raises(ValueError):
2499 load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002500
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002501 def test_dump_privatekey_passphrase(self):
2502 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002503 :py:obj:`dump_privatekey` writes an encrypted PEM when given a
2504 passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002505 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002506 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002507 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002508 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, passphrase)
2509 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002510 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2511 self.assertTrue(isinstance(loadedKey, PKeyType))
2512 self.assertEqual(loadedKey.type(), key.type())
2513 self.assertEqual(loadedKey.bits(), key.bits())
2514
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002515 def test_dump_privatekey_passphraseWrongType(self):
2516 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002517 :py:obj:`dump_privatekey` raises :py:obj:`ValueError` when it is passed
2518 a passphrase with a private key encoded in a format, that doesn't
2519 support encryption.
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002520 """
2521 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor791212d2015-09-05 15:46:08 -04002522 with pytest.raises(ValueError):
2523 dump_privatekey(FILETYPE_ASN1, key, GOOD_CIPHER, "secret")
Ziga Seilnacht376cf972009-12-22 16:04:10 +01002524
Rick Dean5b7b6372009-04-01 11:34:06 -05002525 def test_dump_certificate(self):
2526 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002527 :py:obj:`dump_certificate` writes PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002528 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002529 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002530 cert = load_certificate(FILETYPE_PEM, pemData)
2531 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
2532 self.assertEqual(dumped_pem, cleartextCertificatePEM)
2533 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002534 good_der = _runopenssl(dumped_pem, b"x509", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002535 self.assertEqual(dumped_der, good_der)
2536 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
2537 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
2538 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
2539 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002540 good_text = _runopenssl(dumped_pem, b"x509", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002541 self.assertEqual(dumped_text, good_text)
2542
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002543 def test_dump_privatekey_pem(self):
Rick Dean5b7b6372009-04-01 11:34:06 -05002544 """
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002545 :py:obj:`dump_privatekey` writes a PEM
Rick Dean5b7b6372009-04-01 11:34:06 -05002546 """
2547 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone8e6ce972009-05-13 12:32:49 -04002548 self.assertTrue(key.check())
Rick Dean5b7b6372009-04-01 11:34:06 -05002549 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2550 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002551
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002552 def test_dump_privatekey_asn1(self):
2553 """
2554 :py:obj:`dump_privatekey` writes a DER
2555 """
2556 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2557 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2558
Rick Dean5b7b6372009-04-01 11:34:06 -05002559 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04002560 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002561 good_der = _runopenssl(dumped_pem, b"rsa", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002562 self.assertEqual(dumped_der, good_der)
2563 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2564 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2565 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002566
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002567 def test_dump_privatekey_text(self):
2568 """
2569 :py:obj:`dump_privatekey` writes a text
2570 """
2571 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2572 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2573
Rick Dean5b7b6372009-04-01 11:34:06 -05002574 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002575 good_text = _runopenssl(dumped_pem, b"rsa", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002576 self.assertEqual(dumped_text, good_text)
2577
Cory Benfield6492f7c2015-10-27 16:57:58 +09002578 def test_dump_publickey_pem(self):
2579 """
Cory Benfield11c10192015-10-27 17:23:03 +09002580 dump_publickey writes a PEM.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002581 """
2582 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2583 dumped_pem = dump_publickey(FILETYPE_PEM, key)
2584 self.assertEqual(dumped_pem, cleartextPublicKeyPEM)
2585
2586 def test_dump_publickey_asn1(self):
2587 """
Cory Benfield11c10192015-10-27 17:23:03 +09002588 dump_publickey writes a DER.
Cory Benfield6492f7c2015-10-27 16:57:58 +09002589 """
2590 key = load_publickey(FILETYPE_PEM, cleartextPublicKeyPEM)
2591 dumped_der = dump_publickey(FILETYPE_ASN1, key)
2592 key2 = load_publickey(FILETYPE_ASN1, dumped_der)
2593 dumped_pem2 = dump_publickey(FILETYPE_PEM, key2)
2594 self.assertEqual(dumped_pem2, cleartextPublicKeyPEM)
2595
Rick Dean5b7b6372009-04-01 11:34:06 -05002596 def test_dump_certificate_request(self):
2597 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002598 :py:obj:`dump_certificate_request` writes a PEM, DER, and text.
Rick Dean5b7b6372009-04-01 11:34:06 -05002599 """
Alex Gaynor31287502015-09-05 16:11:27 -04002600 req = load_certificate_request(
2601 FILETYPE_PEM, cleartextCertificateRequestPEM)
Rick Dean5b7b6372009-04-01 11:34:06 -05002602 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2603 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2604 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002605 good_der = _runopenssl(dumped_pem, b"req", b"-outform", b"DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05002606 self.assertEqual(dumped_der, good_der)
2607 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2608 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2609 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2610 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002611 good_text = _runopenssl(dumped_pem, b"req", b"-noout", b"-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05002612 self.assertEqual(dumped_text, good_text)
Jean-Paul Calderoneaf43cdf2010-08-03 18:40:52 -04002613 self.assertRaises(ValueError, dump_certificate_request, 100, req)
Rick Dean5b7b6372009-04-01 11:34:06 -05002614
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002615 def test_dump_privatekey_passphraseCallback(self):
2616 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002617 :py:obj:`dump_privatekey` writes an encrypted PEM when given a callback
2618 which returns the correct passphrase.
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002619 """
Jean-Paul Calderone5be230f2010-08-22 19:27:58 -04002620 passphrase = b("foo")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002621 called = []
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002622
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002623 def cb(writing):
2624 called.append(writing)
2625 return passphrase
2626 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002627 pem = dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
2628 self.assertTrue(isinstance(pem, binary_type))
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04002629 self.assertEqual(called, [True])
2630 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2631 self.assertTrue(isinstance(loadedKey, PKeyType))
2632 self.assertEqual(loadedKey.type(), key.type())
2633 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05002634
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002635 def test_dump_privatekey_passphrase_exception(self):
2636 """
Jean-Paul Calderone5d9d7f12011-09-14 09:48:58 -04002637 :py:obj:`dump_privatekey` should not overwrite the exception raised
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002638 by the passphrase callback.
2639 """
2640 def cb(ignored):
2641 raise ArithmeticError
2642
2643 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002644 with pytest.raises(ArithmeticError):
2645 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht6b90a402009-12-22 14:33:47 +01002646
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002647 def test_dump_privatekey_passphraseCallbackLength(self):
2648 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002649 :py:obj:`crypto.dump_privatekey` should raise an error when the
2650 passphrase provided by the callback is too long, not silently truncate
2651 it.
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002652 """
2653 def cb(ignored):
2654 return "a" * 1025
2655
2656 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Alex Gaynor85b49702015-09-05 16:30:59 -04002657 with pytest.raises(ValueError):
2658 dump_privatekey(FILETYPE_PEM, key, GOOD_CIPHER, cb)
Ziga Seilnacht781295a2009-12-22 14:58:01 +01002659
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002660 def test_load_pkcs7_data_pem(self):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002661 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002662 :py:obj:`load_pkcs7_data` accepts a PKCS#7 string and returns an
2663 instance of :py:obj:`PKCS7Type`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002664 """
2665 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2666 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2667
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002668 def test_load_pkcs7_data_asn1(self):
Alex Gaynor9875a912014-08-14 13:35:05 -07002669 """
2670 :py:obj:`load_pkcs7_data` accepts a bytes containing ASN1 data
2671 representing PKCS#7 and returns an instance of :py:obj`PKCS7Type`.
2672 """
Alex Gaynor4b9c96a2014-08-14 09:51:48 -07002673 pkcs7 = load_pkcs7_data(FILETYPE_ASN1, pkcs7DataASN1)
2674 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2675
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002676 def test_load_pkcs7_data_invalid(self):
2677 """
2678 If the data passed to :py:obj:`load_pkcs7_data` is invalid,
2679 :py:obj:`Error` is raised.
2680 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002681 self.assertRaises(Error, load_pkcs7_data, FILETYPE_PEM, b"foo")
Jean-Paul Calderonee82e3252013-03-03 10:14:10 -08002682
2683
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002684class LoadCertificateTests(TestCase):
2685 """
2686 Tests for :py:obj:`load_certificate_request`.
2687 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002688
Jean-Paul Calderone4a68b402013-12-29 16:54:58 -05002689 def test_badFileType(self):
2690 """
2691 If the file type passed to :py:obj:`load_certificate_request` is
2692 neither :py:obj:`FILETYPE_PEM` nor :py:obj:`FILETYPE_ASN1` then
2693 :py:class:`ValueError` is raised.
2694 """
2695 self.assertRaises(ValueError, load_certificate_request, object(), b"")
2696
2697
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002698class PKCS7Tests(TestCase):
2699 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002700 Tests for :py:obj:`PKCS7Type`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002701 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002702
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002703 def test_type(self):
2704 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002705 :py:obj:`PKCS7Type` is a type object.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002706 """
2707 self.assertTrue(isinstance(PKCS7Type, type))
2708 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2709
2710 # XXX This doesn't currently work.
2711 # self.assertIdentical(PKCS7, PKCS7Type)
2712
Jean-Paul Calderonefe1b9bd2010-08-03 18:00:21 -04002713 # XXX Opposite results for all these following methods
2714
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002715 def test_type_is_signed_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002716 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002717 :py:obj:`PKCS7Type.type_is_signed` raises :py:obj:`TypeError` if called
2718 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002719 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002720 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2721 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2722
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002723 def test_type_is_signed(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002724 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002725 :py:obj:`PKCS7Type.type_is_signed` returns :py:obj:`True` if the PKCS7
2726 object is of the type *signed*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002727 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002728 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2729 self.assertTrue(pkcs7.type_is_signed())
2730
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002731 def test_type_is_enveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002732 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002733 :py:obj:`PKCS7Type.type_is_enveloped` raises :py:obj:`TypeError` if
2734 called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002735 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002736 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2737 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2738
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002739 def test_type_is_enveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002740 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002741 :py:obj:`PKCS7Type.type_is_enveloped` returns :py:obj:`False` if the
2742 PKCS7 object is not of the type *enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002743 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002744 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2745 self.assertFalse(pkcs7.type_is_enveloped())
2746
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002747 def test_type_is_signedAndEnveloped_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002748 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002749 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` raises
2750 :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002751 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002752 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2753 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2754
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002755 def test_type_is_signedAndEnveloped(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002756 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002757 :py:obj:`PKCS7Type.type_is_signedAndEnveloped` returns :py:obj:`False`
2758 if the PKCS7 object is not of the type *signed and enveloped*.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002759 """
Jean-Paul Calderone07c93742010-07-30 10:53:41 -04002760 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2761 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2762
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002763 def test_type_is_data(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002764 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002765 :py:obj:`PKCS7Type.type_is_data` returns :py:obj:`False` if the PKCS7
2766 object is not of the type data.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002767 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002768 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2769 self.assertFalse(pkcs7.type_is_data())
2770
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002771 def test_type_is_data_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002772 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002773 :py:obj:`PKCS7Type.type_is_data` raises :py:obj:`TypeError` if called
2774 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002775 """
Jean-Paul Calderoneb4754b92010-07-30 11:00:08 -04002776 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2777 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2778
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002779 def test_get_type_name_wrong_args(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002780 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002781 :py:obj:`PKCS7Type.get_type_name` raises :py:obj:`TypeError` if called
2782 with any arguments.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002783 """
Jean-Paul Calderone97b28ca2010-07-30 10:56:07 -04002784 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2785 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2786
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002787 def test_get_type_name(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002788 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002789 :py:obj:`PKCS7Type.get_type_name` returns a :py:obj:`str` giving the
2790 type name.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002791 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002792 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
Jean-Paul Calderone07640f12010-08-22 17:14:43 -04002793 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002794
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002795 def test_attribute(self):
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002796 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002797 If an attribute other than one of the methods tested here is accessed
2798 on an instance of :py:obj:`PKCS7Type`, :py:obj:`AttributeError` is
2799 raised.
Jean-Paul Calderoneaa6c0692010-09-08 22:43:09 -04002800 """
Jean-Paul Calderone4cbe05e2010-07-30 10:55:30 -04002801 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2802 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2803
2804
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002805class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002806 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002807 Tests for :py:obj:`OpenSSL.crypto.NetscapeSPKI`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002808 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002809
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002810 def signable(self):
2811 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002812 Return a new :py:obj:`NetscapeSPKI` for use with signing tests.
Jean-Paul Calderoneb9725592010-08-03 18:17:22 -04002813 """
2814 return NetscapeSPKI()
2815
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002816 def test_type(self):
2817 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002818 :py:obj:`NetscapeSPKI` and :py:obj:`NetscapeSPKIType` refer to the same
2819 type object and can be used to create instances of that type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002820 """
2821 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2822 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2823
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002824 def test_construction(self):
2825 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002826 :py:obj:`NetscapeSPKI` returns an instance of
2827 :py:obj:`NetscapeSPKIType`.
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04002828 """
2829 nspki = NetscapeSPKI()
2830 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2831
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002832 def test_invalid_attribute(self):
2833 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002834 Accessing a non-existent attribute of a :py:obj:`NetscapeSPKI` instance
2835 causes an :py:obj:`AttributeError` to be raised.
Jean-Paul Calderone969efaa2010-08-03 18:19:19 -04002836 """
2837 nspki = NetscapeSPKI()
2838 self.assertRaises(AttributeError, lambda: nspki.foo)
2839
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002840 def test_b64_encode(self):
2841 """
Alex Gaynor791212d2015-09-05 15:46:08 -04002842 :py:obj:`NetscapeSPKI.b64_encode` encodes the certificate to a base64
2843 blob.
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002844 """
2845 nspki = NetscapeSPKI()
2846 blob = nspki.b64_encode()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002847 self.assertTrue(isinstance(blob, binary_type))
Jean-Paul Calderone06ada9f2010-08-03 18:26:52 -04002848
2849
Rick Dean536ba022009-07-24 23:57:27 -05002850class RevokedTests(TestCase):
2851 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002852 Tests for :py:obj:`OpenSSL.crypto.Revoked`
Rick Dean536ba022009-07-24 23:57:27 -05002853 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002854
Rick Dean536ba022009-07-24 23:57:27 -05002855 def test_construction(self):
2856 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002857 Confirm we can create :py:obj:`OpenSSL.crypto.Revoked`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002858 that it is empty.
2859 """
2860 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002861 self.assertTrue(isinstance(revoked, Revoked))
2862 self.assertEquals(type(revoked), Revoked)
2863 self.assertEquals(revoked.get_serial(), b('00'))
2864 self.assertEquals(revoked.get_rev_date(), None)
2865 self.assertEquals(revoked.get_reason(), None)
Rick Dean536ba022009-07-24 23:57:27 -05002866
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002867 def test_construction_wrong_args(self):
2868 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002869 Calling :py:obj:`OpenSSL.crypto.Revoked` with any arguments results
2870 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002871 """
2872 self.assertRaises(TypeError, Revoked, None)
2873 self.assertRaises(TypeError, Revoked, 1)
2874 self.assertRaises(TypeError, Revoked, "foo")
2875
Rick Dean536ba022009-07-24 23:57:27 -05002876 def test_serial(self):
2877 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002878 Confirm we can set and get serial numbers from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002879 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002880 with grace.
2881 """
2882 revoked = Revoked()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002883 ret = revoked.set_serial(b('10b'))
2884 self.assertEquals(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002885 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002886 self.assertEquals(ser, b('010B'))
Rick Dean536ba022009-07-24 23:57:27 -05002887
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002888 revoked.set_serial(b('31ppp')) # a type error would be nice
Rick Dean536ba022009-07-24 23:57:27 -05002889 ser = revoked.get_serial()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002890 self.assertEquals(ser, b('31'))
Rick Dean536ba022009-07-24 23:57:27 -05002891
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002892 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
Rick Dean536ba022009-07-24 23:57:27 -05002893 self.assertRaises(TypeError, revoked.set_serial, 100)
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002894 self.assertRaises(TypeError, revoked.get_serial, 1)
2895 self.assertRaises(TypeError, revoked.get_serial, None)
2896 self.assertRaises(TypeError, revoked.get_serial, "")
Rick Dean536ba022009-07-24 23:57:27 -05002897
Rick Dean536ba022009-07-24 23:57:27 -05002898 def test_date(self):
2899 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002900 Confirm we can set and get revocation dates from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002901 :py:obj:`OpenSSL.crypto.Revoked`. Confirm errors are handled
Rick Dean536ba022009-07-24 23:57:27 -05002902 with grace.
2903 """
2904 revoked = Revoked()
2905 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002906 self.assertEquals(date, None)
Rick Dean536ba022009-07-24 23:57:27 -05002907
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002908 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002909 ret = revoked.set_rev_date(now)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002910 self.assertEqual(ret, None)
Rick Dean536ba022009-07-24 23:57:27 -05002911 date = revoked.get_rev_date()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002912 self.assertEqual(date, now)
Rick Dean536ba022009-07-24 23:57:27 -05002913
Rick Dean6385faf2009-07-26 00:07:47 -05002914 def test_reason(self):
2915 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05002916 Confirm we can set and get revocation reasons from
Jonathan Ballet648875f2011-07-16 14:14:58 +09002917 :py:obj:`OpenSSL.crypto.Revoked`. The "get" need to work
Rick Dean6385faf2009-07-26 00:07:47 -05002918 as "set". Likewise, each reason of all_reasons() must work.
2919 """
2920 revoked = Revoked()
2921 for r in revoked.all_reasons():
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002922 for x in range(2):
Rick Dean6385faf2009-07-26 00:07:47 -05002923 ret = revoked.set_reason(r)
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002924 self.assertEquals(ret, None)
Rick Dean6385faf2009-07-26 00:07:47 -05002925 reason = revoked.get_reason()
Jean-Paul Calderoneeacad4a2010-08-22 17:12:55 -04002926 self.assertEquals(
2927 reason.lower().replace(b(' '), b('')),
2928 r.lower().replace(b(' '), b('')))
Alex Gaynoraceb3e22015-09-05 12:00:22 -04002929 r = reason # again with the resp of get
Rick Dean6385faf2009-07-26 00:07:47 -05002930
2931 revoked.set_reason(None)
2932 self.assertEqual(revoked.get_reason(), None)
2933
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002934 def test_set_reason_wrong_arguments(self):
Rick Dean6385faf2009-07-26 00:07:47 -05002935 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002936 Calling :py:obj:`OpenSSL.crypto.Revoked.set_reason` with other than
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002937 one argument, or an argument which isn't a valid reason,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002938 results in :py:obj:`TypeError` or :py:obj:`ValueError` being raised.
Rick Dean6385faf2009-07-26 00:07:47 -05002939 """
2940 revoked = Revoked()
2941 self.assertRaises(TypeError, revoked.set_reason, 100)
Jean-Paul Calderone281b62b2010-08-28 14:22:29 -04002942 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
Rick Dean6385faf2009-07-26 00:07:47 -05002943
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002944 def test_get_reason_wrong_arguments(self):
2945 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002946 Calling :py:obj:`OpenSSL.crypto.Revoked.get_reason` with any
2947 arguments results in :py:obj:`TypeError` being raised.
Jean-Paul Calderone4f74bfe2010-01-30 14:32:49 -05002948 """
2949 revoked = Revoked()
2950 self.assertRaises(TypeError, revoked.get_reason, None)
2951 self.assertRaises(TypeError, revoked.get_reason, 1)
2952 self.assertRaises(TypeError, revoked.get_reason, "foo")
2953
2954
Rick Dean536ba022009-07-24 23:57:27 -05002955class CRLTests(TestCase):
2956 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002957 Tests for :py:obj:`OpenSSL.crypto.CRL`
Rick Dean536ba022009-07-24 23:57:27 -05002958 """
2959 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2960 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2961
2962 def test_construction(self):
2963 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002964 Confirm we can create :py:obj:`OpenSSL.crypto.CRL`. Check
Rick Dean536ba022009-07-24 23:57:27 -05002965 that it is empty
2966 """
2967 crl = CRL()
Alex Gaynor7f636492015-09-04 13:26:52 -04002968 self.assertTrue(isinstance(crl, CRL))
Rick Dean536ba022009-07-24 23:57:27 -05002969 self.assertEqual(crl.get_revoked(), None)
2970
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05002971 def test_construction_wrong_args(self):
2972 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002973 Calling :py:obj:`OpenSSL.crypto.CRL` with any number of arguments
2974 results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone2efd03e2010-01-30 13:59:55 -05002975 """
2976 self.assertRaises(TypeError, CRL, 1)
2977 self.assertRaises(TypeError, CRL, "")
2978 self.assertRaises(TypeError, CRL, None)
2979
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002980 def _get_crl(self):
Rick Dean536ba022009-07-24 23:57:27 -05002981 """
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002982 Get a new ``CRL`` with a revocation.
Rick Dean536ba022009-07-24 23:57:27 -05002983 """
2984 crl = CRL()
2985 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002986 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05002987 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04002988 revoked.set_serial(b('3ab'))
2989 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05002990 crl.add_revoked(revoked)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002991 return crl
Rick Dean536ba022009-07-24 23:57:27 -05002992
Jean-Paul Calderone60432792015-04-13 12:26:07 -04002993 def test_export_pem(self):
2994 """
2995 If not passed a format, ``CRL.export`` returns a "PEM" format string
2996 representing a serial number, a revoked reason, and certificate issuer
2997 information.
2998 """
2999 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003000 # PEM format
3001 dumped_crl = crl.export(self.cert, self.pkey, days=20)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003002 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003003
3004 # These magic values are based on the way the CRL above was constructed
3005 # and with what certificate it was exported.
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003006 text.index(b('Serial Number: 03AB'))
3007 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003008 text.index(
3009 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3010 )
3011
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003012 def test_export_der(self):
3013 """
3014 If passed ``FILETYPE_ASN1`` for the format, ``CRL.export`` returns a
3015 "DER" format string representing a serial number, a revoked reason, and
3016 certificate issuer information.
3017 """
3018 crl = self._get_crl()
Rick Dean536ba022009-07-24 23:57:27 -05003019
3020 # DER format
3021 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003022 text = _runopenssl(
3023 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3024 )
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003025 text.index(b('Serial Number: 03AB'))
3026 text.index(b('Superseded'))
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003027 text.index(
3028 b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA')
3029 )
3030
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003031 def test_export_text(self):
3032 """
3033 If passed ``FILETYPE_TEXT`` for the format, ``CRL.export`` returns a
3034 text format string like the one produced by the openssl command line
3035 tool.
3036 """
3037 crl = self._get_crl()
3038
3039 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
3040 text = _runopenssl(
3041 dumped_crl, b"crl", b"-noout", b"-text", b"-inform", b"DER"
3042 )
Rick Dean536ba022009-07-24 23:57:27 -05003043
3044 # text format
3045 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
3046 self.assertEqual(text, dumped_text)
3047
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003048 def test_export_custom_digest(self):
3049 """
3050 If passed the name of a digest function, ``CRL.export`` uses a
3051 signature algorithm based on that digest function.
3052 """
3053 crl = self._get_crl()
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003054 dumped_crl = crl.export(self.cert, self.pkey, digest=b"sha1")
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003055 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3056 text.index(b('Signature Algorithm: sha1'))
3057
Jean-Paul Calderonecce22d02015-04-13 13:56:09 -04003058 def test_export_md5_digest(self):
3059 """
3060 If passed md5 as the digest function, ``CRL.export`` uses md5 and does
3061 not emit a deprecation warning.
3062 """
3063 crl = self._get_crl()
3064 with catch_warnings(record=True) as catcher:
3065 simplefilter("always")
3066 self.assertEqual(0, len(catcher))
3067 dumped_crl = crl.export(self.cert, self.pkey, digest=b"md5")
3068 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3069 text.index(b('Signature Algorithm: md5'))
3070
Jean-Paul Calderone60432792015-04-13 12:26:07 -04003071 def test_export_default_digest(self):
3072 """
3073 If not passed the name of a digest function, ``CRL.export`` uses a
3074 signature algorithm based on MD5 and emits a deprecation warning.
3075 """
3076 crl = self._get_crl()
3077 with catch_warnings(record=True) as catcher:
3078 simplefilter("always")
3079 dumped_crl = crl.export(self.cert, self.pkey)
3080 self.assertEqual(
3081 "The default message digest (md5) is deprecated. "
3082 "Pass the name of a message digest explicitly.",
3083 str(catcher[0].message),
3084 )
Bulat Gaifullin1966c972014-09-22 09:47:20 +04003085 text = _runopenssl(dumped_crl, b"crl", b"-noout", b"-text")
3086 text.index(b('Signature Algorithm: md5'))
3087
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003088 def test_export_invalid(self):
3089 """
3090 If :py:obj:`CRL.export` is used with an uninitialized :py:obj:`X509`
Jean-Paul Calderoneb5871072012-03-09 14:58:00 -08003091 instance, :py:obj:`OpenSSL.crypto.Error` is raised.
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -04003092 """
3093 crl = CRL()
3094 self.assertRaises(Error, crl.export, X509(), PKey())
3095
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003096 def test_add_revoked_keyword(self):
3097 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003098 :py:obj:`OpenSSL.CRL.add_revoked` accepts its single argument as the
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04003099 ``revoked`` keyword argument.
Jean-Paul Calderone56515342010-01-30 13:49:38 -05003100 """
3101 crl = CRL()
3102 revoked = Revoked()
3103 crl.add_revoked(revoked=revoked)
3104 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
3105
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003106 def test_export_wrong_args(self):
3107 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003108 Calling :py:obj:`OpenSSL.CRL.export` with fewer than two or more than
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003109 four arguments, or with arguments other than the certificate,
3110 private key, integer file type, and integer number of days it
Jonathan Ballet648875f2011-07-16 14:14:58 +09003111 expects, results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone883ca4b2010-01-30 13:55:13 -05003112 """
3113 crl = CRL()
3114 self.assertRaises(TypeError, crl.export)
3115 self.assertRaises(TypeError, crl.export, self.cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003116 with pytest.raises(TypeError):
3117 crl.export(self.cert, self.pkey, FILETYPE_PEM, 10, "md5", "foo")
3118 with pytest.raises(TypeError):
3119 crl.export(None, self.pkey, FILETYPE_PEM, 10)
3120 with pytest.raises(TypeError):
3121 crl.export(self.cert, None, FILETYPE_PEM, 10)
3122 with pytest.raises(TypeError):
3123 crl.export(self.cert, self.pkey, None, 10)
Jean-Paul Calderonef1515862010-01-30 13:57:03 -05003124 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
3125
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003126 def test_export_unknown_filetype(self):
3127 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003128 Calling :py:obj:`OpenSSL.CRL.export` with a file type other than
Alex Gaynor791212d2015-09-05 15:46:08 -04003129 :py:obj:`FILETYPE_PEM`, :py:obj:`FILETYPE_ASN1`, or
3130 :py:obj:`FILETYPE_TEXT` results in a :py:obj:`ValueError` being raised.
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003131 """
3132 crl = CRL()
Alex Gaynor85b49702015-09-05 16:30:59 -04003133 with pytest.raises(ValueError):
3134 crl.export(self.cert, self.pkey, 100, 10)
Jean-Paul Calderoneea198422010-01-30 13:58:23 -05003135
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003136 def test_export_unknown_digest(self):
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003137 """
Alex Gaynorca87ff62015-09-04 23:31:03 -04003138 Calling :py:obj:`OpenSSL.CRL.export` with an unsupported digest results
Bulat Gaifullin5f9eea42014-09-23 19:35:15 +04003139 in a :py:obj:`ValueError` being raised.
3140 """
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003141 crl = CRL()
Jean-Paul Calderone9be85192015-04-13 21:20:51 -04003142 self.assertRaises(
3143 ValueError,
3144 crl.export,
3145 self.cert, self.pkey, FILETYPE_PEM, 10, b"strange-digest"
3146 )
Bulat Gaifullin925f7862014-09-22 10:10:44 +04003147
Rick Dean536ba022009-07-24 23:57:27 -05003148 def test_get_revoked(self):
3149 """
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003150 Use python to create a simple CRL with two revocations.
Alex Gaynor791212d2015-09-05 15:46:08 -04003151 Get back the :py:obj:`Revoked` using :py:obj:`OpenSSL.CRL.get_revoked`
3152 and verify them.
Rick Dean536ba022009-07-24 23:57:27 -05003153 """
3154 crl = CRL()
3155
3156 revoked = Revoked()
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003157 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
Rick Dean536ba022009-07-24 23:57:27 -05003158 revoked.set_rev_date(now)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003159 revoked.set_serial(b('3ab'))
Rick Dean536ba022009-07-24 23:57:27 -05003160 crl.add_revoked(revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003161 revoked.set_serial(b('100'))
3162 revoked.set_reason(b('sUpErSeDEd'))
Rick Dean536ba022009-07-24 23:57:27 -05003163 crl.add_revoked(revoked)
3164
3165 revs = crl.get_revoked()
3166 self.assertEqual(len(revs), 2)
3167 self.assertEqual(type(revs[0]), Revoked)
3168 self.assertEqual(type(revs[1]), Revoked)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003169 self.assertEqual(revs[0].get_serial(), b('03AB'))
3170 self.assertEqual(revs[1].get_serial(), b('0100'))
Rick Dean536ba022009-07-24 23:57:27 -05003171 self.assertEqual(revs[0].get_rev_date(), now)
3172 self.assertEqual(revs[1].get_rev_date(), now)
3173
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003174 def test_get_revoked_wrong_args(self):
3175 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003176 Calling :py:obj:`OpenSSL.CRL.get_revoked` with any arguments results
3177 in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone46bdce42010-01-30 13:44:16 -05003178 """
3179 crl = CRL()
3180 self.assertRaises(TypeError, crl.get_revoked, None)
3181 self.assertRaises(TypeError, crl.get_revoked, 1)
3182 self.assertRaises(TypeError, crl.get_revoked, "")
3183 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
3184
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003185 def test_add_revoked_wrong_args(self):
3186 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003187 Calling :py:obj:`OpenSSL.CRL.add_revoked` with other than one
3188 argument results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderoneecef6fa2010-01-30 13:47:18 -05003189 """
3190 crl = CRL()
3191 self.assertRaises(TypeError, crl.add_revoked)
3192 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
3193 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
3194
Rick Dean536ba022009-07-24 23:57:27 -05003195 def test_load_crl(self):
3196 """
3197 Load a known CRL and inspect its revocations. Both
3198 PEM and DER formats are loaded.
3199 """
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003200 crl = load_crl(FILETYPE_PEM, crlData)
Rick Dean536ba022009-07-24 23:57:27 -05003201 revs = crl.get_revoked()
3202 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003203 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003204 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003205 self.assertEqual(revs[1].get_serial(), b('0100'))
3206 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003207
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003208 der = _runopenssl(crlData, b"crl", b"-outform", b"DER")
Jean-Paul Calderoneb98eae02010-01-30 13:18:04 -05003209 crl = load_crl(FILETYPE_ASN1, der)
Rick Dean536ba022009-07-24 23:57:27 -05003210 revs = crl.get_revoked()
3211 self.assertEqual(len(revs), 2)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003212 self.assertEqual(revs[0].get_serial(), b('03AB'))
Rick Dean6385faf2009-07-26 00:07:47 -05003213 self.assertEqual(revs[0].get_reason(), None)
Jean-Paul Calderoneb894fe12010-08-22 19:30:19 -04003214 self.assertEqual(revs[1].get_serial(), b('0100'))
3215 self.assertEqual(revs[1].get_reason(), b('Superseded'))
Rick Dean536ba022009-07-24 23:57:27 -05003216
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003217 def test_load_crl_wrong_args(self):
3218 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003219 Calling :py:obj:`OpenSSL.crypto.load_crl` with other than two
3220 arguments results in a :py:obj:`TypeError` being raised.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003221 """
3222 self.assertRaises(TypeError, load_crl)
3223 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
3224 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
3225
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003226 def test_load_crl_bad_filetype(self):
3227 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003228 Calling :py:obj:`OpenSSL.crypto.load_crl` with an unknown file type
3229 raises a :py:obj:`ValueError`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003230 """
3231 self.assertRaises(ValueError, load_crl, 100, crlData)
3232
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003233 def test_load_crl_bad_data(self):
3234 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003235 Calling :py:obj:`OpenSSL.crypto.load_crl` with file data which can't
3236 be loaded raises a :py:obj:`OpenSSL.crypto.Error`.
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003237 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05003238 self.assertRaises(Error, load_crl, FILETYPE_PEM, b"hello, world")
Jean-Paul Calderone3eb5cc72010-01-30 15:24:40 -05003239
Dominic Chenf05b2122015-10-13 16:32:35 +00003240 def test_dump_crl(self):
3241 """
3242 The dumped CRL matches the original input.
3243 """
3244 crl = load_crl(FILETYPE_PEM, crlData)
3245 buf = dump_crl(FILETYPE_PEM, crl)
3246 assert buf == crlData
3247
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04003248
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003249class X509StoreContextTests(TestCase):
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003250 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003251 Tests for :py:obj:`OpenSSL.crypto.X509StoreContext`.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003252 """
3253 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3254 intermediate_cert = load_certificate(FILETYPE_PEM, intermediate_cert_pem)
Alex Gaynor31287502015-09-05 16:11:27 -04003255 intermediate_server_cert = load_certificate(
3256 FILETYPE_PEM, intermediate_server_cert_pem)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003257
3258 def test_valid(self):
3259 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003260 :py:obj:`verify_certificate` returns ``None`` when called with a
3261 certificate and valid chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003262 """
3263 store = X509Store()
3264 store.add_cert(self.root_cert)
3265 store.add_cert(self.intermediate_cert)
3266 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003267 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003268
3269 def test_reuse(self):
3270 """
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003271 :py:obj:`verify_certificate` can be called multiple times with the same
Jean-Paul Calderone06e01b92015-01-18 15:43:13 -05003272 ``X509StoreContext`` instance to produce the same result.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003273 """
3274 store = X509Store()
3275 store.add_cert(self.root_cert)
3276 store.add_cert(self.intermediate_cert)
3277 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003278 self.assertEqual(store_ctx.verify_certificate(), None)
3279 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003280
3281 def test_trusted_self_signed(self):
3282 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003283 :py:obj:`verify_certificate` returns ``None`` when called with a
3284 self-signed certificate and itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003285 """
3286 store = X509Store()
3287 store.add_cert(self.root_cert)
3288 store_ctx = X509StoreContext(store, self.root_cert)
Stephen Holsapple08ffaa62015-01-30 17:18:40 -08003289 self.assertEqual(store_ctx.verify_certificate(), None)
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003290
3291 def test_untrusted_self_signed(self):
3292 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003293 :py:obj:`verify_certificate` raises error when a self-signed
3294 certificate is verified without itself in the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003295 """
3296 store = X509Store()
3297 store_ctx = X509StoreContext(store, self.root_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003298 with pytest.raises(X509StoreContextError) as exc:
3299 store_ctx.verify_certificate()
3300
3301 assert exc.value.args[0][2] == 'self signed certificate'
3302 assert exc.value.certificate.get_subject().CN == 'Testing Root CA'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003303
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003304 def test_invalid_chain_no_root(self):
3305 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003306 :py:obj:`verify_certificate` raises error when a root certificate is
3307 missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003308 """
3309 store = X509Store()
3310 store.add_cert(self.intermediate_cert)
3311 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003312
3313 with pytest.raises(X509StoreContextError) as exc:
3314 store_ctx.verify_certificate()
3315
3316 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3317 assert exc.value.certificate.get_subject().CN == 'intermediate'
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003318
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003319 def test_invalid_chain_no_intermediate(self):
3320 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003321 :py:obj:`verify_certificate` raises error when an intermediate
3322 certificate is missing from the chain.
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003323 """
3324 store = X509Store()
3325 store.add_cert(self.root_cert)
3326 store_ctx = X509StoreContext(store, self.intermediate_server_cert)
Jean-Paul Calderone517816e2015-01-18 15:39:26 -05003327
Alex Gaynor85b49702015-09-05 16:30:59 -04003328 with pytest.raises(X509StoreContextError) as exc:
3329 store_ctx.verify_certificate()
3330
3331 assert exc.value.args[0][2] == 'unable to get local issuer certificate'
3332 assert exc.value.certificate.get_subject().CN == 'intermediate-service'
Stephen Holsapple0d9815f2014-08-27 19:36:53 -07003333
Stephen Holsapple46a09252015-02-12 14:45:43 -08003334 def test_modification_pre_verify(self):
3335 """
3336 :py:obj:`verify_certificate` can use a store context modified after
3337 instantiation.
3338 """
3339 store_bad = X509Store()
3340 store_bad.add_cert(self.intermediate_cert)
3341 store_good = X509Store()
3342 store_good.add_cert(self.root_cert)
3343 store_good.add_cert(self.intermediate_cert)
3344 store_ctx = X509StoreContext(store_bad, self.intermediate_server_cert)
Alex Gaynor85b49702015-09-05 16:30:59 -04003345
3346 with pytest.raises(X509StoreContextError) as exc:
3347 store_ctx.verify_certificate()
3348
3349 assert exc.value.args[0][2] == 'unable to get issuer certificate'
3350 assert exc.value.certificate.get_subject().CN == 'intermediate'
3351
Stephen Holsapple46a09252015-02-12 14:45:43 -08003352 store_ctx.set_store(store_good)
3353 self.assertEqual(store_ctx.verify_certificate(), None)
3354
3355
James Yonan7c2e5d32010-02-27 05:45:50 -07003356class SignVerifyTests(TestCase):
3357 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003358 Tests for :py:obj:`OpenSSL.crypto.sign` and
3359 :py:obj:`OpenSSL.crypto.verify`.
James Yonan7c2e5d32010-02-27 05:45:50 -07003360 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003361
James Yonan7c2e5d32010-02-27 05:45:50 -07003362 def test_sign_verify(self):
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003363 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003364 :py:obj:`sign` generates a cryptographic signature which
3365 :py:obj:`verify` can check.
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003366 """
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003367 content = b(
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003368 "It was a bright cold day in April, and the clocks were striking "
3369 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
3370 "effort to escape the vile wind, slipped quickly through the "
3371 "glass doors of Victory Mansions, though not quickly enough to "
3372 "prevent a swirl of gritty dust from entering along with him.")
3373
3374 # sign the content with this private key
Jean-Paul Calderonef3cb9d82010-06-22 10:29:33 -04003375 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
Jean-Paul Calderoneb98ce212010-06-22 09:46:27 -04003376 # verify the content with this cert
3377 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3378 # certificate unrelated to priv_key, used to trigger an error
3379 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
James Yonan7c2e5d32010-02-27 05:45:50 -07003380
Jean-Paul Calderoned08feb02010-10-12 21:53:24 -04003381 for digest in ['md5', 'sha1']:
James Yonan7c2e5d32010-02-27 05:45:50 -07003382 sig = sign(priv_key, content, digest)
3383
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003384 # Verify the signature of content, will throw an exception if
3385 # error.
James Yonan7c2e5d32010-02-27 05:45:50 -07003386 verify(good_cert, sig, content, digest)
3387
3388 # This should fail because the certificate doesn't match the
3389 # private key that was used to sign the content.
3390 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
3391
3392 # This should fail because we've "tainted" the content after
3393 # signing it.
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003394 self.assertRaises(
3395 Error, verify,
3396 good_cert, sig, content + b("tainted"), digest)
James Yonan7c2e5d32010-02-27 05:45:50 -07003397
3398 # test that unknown digest types fail
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003399 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003400 ValueError, sign, priv_key, content, "strange-digest")
Jean-Paul Calderoneea305c52010-08-28 14:41:07 -04003401 self.assertRaises(
Jean-Paul Calderone9538f142010-10-13 22:13:40 -04003402 ValueError, verify, good_cert, sig, content, "strange-digest")
James Yonan7c2e5d32010-02-27 05:45:50 -07003403
Abraham Martinc5484ba2015-03-25 15:33:05 +00003404 def test_sign_verify_with_text(self):
3405 """
Alex Gaynor791212d2015-09-05 15:46:08 -04003406 :py:obj:`sign` generates a cryptographic signature which
3407 :py:obj:`verify` can check. Deprecation warnings raised because using
3408 text instead of bytes as content
Abraham Martinc5484ba2015-03-25 15:33:05 +00003409 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003410 content = (
Jean-Paul Calderone362c1f52015-03-29 08:01:39 -04003411 b"It was a bright cold day in April, and the clocks were striking "
3412 b"thirteen. Winston Smith, his chin nuzzled into his breast in an "
3413 b"effort to escape the vile wind, slipped quickly through the "
3414 b"glass doors of Victory Mansions, though not quickly enough to "
3415 b"prevent a swirl of gritty dust from entering along with him."
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003416 ).decode("ascii")
Abraham Martinc5484ba2015-03-25 15:33:05 +00003417
3418 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3419 cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3420 for digest in ['md5', 'sha1']:
3421 with catch_warnings(record=True) as w:
3422 simplefilter("always")
3423 sig = sign(priv_key, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003424
3425 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003426 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003427 WARNING_TYPE_EXPECTED
3428 ),
3429 str(w[-1].message)
3430 )
3431 self.assertIs(w[-1].category, DeprecationWarning)
3432
Abraham Martinc5484ba2015-03-25 15:33:05 +00003433 with catch_warnings(record=True) as w:
3434 simplefilter("always")
3435 verify(cert, sig, content, digest)
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003436
3437 self.assertEqual(
Jean-Paul Calderone13a0e652015-03-29 07:58:51 -04003438 "{0} for data is no longer accepted, use bytes".format(
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04003439 WARNING_TYPE_EXPECTED
3440 ),
3441 str(w[-1].message)
3442 )
3443 self.assertIs(w[-1].category, DeprecationWarning)
Abraham Martinc5484ba2015-03-25 15:33:05 +00003444
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003445 def test_sign_nulls(self):
3446 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09003447 :py:obj:`sign` produces a signature for a string with embedded nulls.
Jean-Paul Calderone9828f662010-12-08 22:57:26 -05003448 """
3449 content = b("Watch out! \0 Did you see it?")
3450 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
3451 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
3452 sig = sign(priv_key, content, "sha1")
3453 verify(good_cert, sig, content, "sha1")
3454
3455
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003456class EllipticCurveTests(TestCase):
3457 """
3458 Tests for :py:class:`_EllipticCurve`, :py:obj:`get_elliptic_curve`, and
3459 :py:obj:`get_elliptic_curves`.
3460 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003461
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003462 def test_set(self):
3463 """
3464 :py:obj:`get_elliptic_curves` returns a :py:obj:`set`.
3465 """
3466 self.assertIsInstance(get_elliptic_curves(), set)
3467
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003468 def test_some_curves(self):
3469 """
3470 If :py:mod:`cryptography` has elliptic curve support then the set
3471 returned by :py:obj:`get_elliptic_curves` has some elliptic curves in
3472 it.
3473
3474 There could be an OpenSSL that violates this assumption. If so, this
3475 test will fail and we'll find out.
3476 """
3477 curves = get_elliptic_curves()
3478 if lib.Cryptography_HAS_EC:
3479 self.assertTrue(curves)
3480 else:
3481 self.assertFalse(curves)
3482
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003483 def test_a_curve(self):
3484 """
3485 :py:obj:`get_elliptic_curve` can be used to retrieve a particular
3486 supported curve.
3487 """
3488 curves = get_elliptic_curves()
3489 if curves:
3490 curve = next(iter(curves))
3491 self.assertEqual(curve.name, get_elliptic_curve(curve.name).name)
3492 else:
Jean-Paul Calderoneeb86f3a2014-04-19 09:45:57 -04003493 self.assertRaises(ValueError, get_elliptic_curve, u("prime256v1"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003494
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003495 def test_not_a_curve(self):
3496 """
3497 :py:obj:`get_elliptic_curve` raises :py:class:`ValueError` if called
3498 with a name which does not identify a supported curve.
3499 """
3500 self.assertRaises(
Jean-Paul Calderone5a82db92014-04-19 09:51:29 -04003501 ValueError, get_elliptic_curve, u("this curve was just invented"))
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003502
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003503 def test_repr(self):
3504 """
3505 The string representation of a curve object includes simply states the
3506 object is a curve and what its name is.
3507 """
3508 curves = get_elliptic_curves()
3509 if curves:
3510 curve = next(iter(curves))
3511 self.assertEqual("<Curve %r>" % (curve.name,), repr(curve))
3512
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04003513 def test_to_EC_KEY(self):
3514 """
3515 The curve object can export a version of itself as an EC_KEY* via the
3516 private :py:meth:`_EllipticCurve._to_EC_KEY`.
3517 """
3518 curves = get_elliptic_curves()
3519 if curves:
3520 curve = next(iter(curves))
3521 # It's not easy to assert anything about this object. However, see
3522 # leakcheck/crypto.py for a test that demonstrates it at least does
3523 # not leak memory.
3524 curve._to_EC_KEY()
3525
3526
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003527class EllipticCurveFactory(object):
3528 """
3529 A helper to get the names of two curves.
3530 """
Alex Gaynoraceb3e22015-09-05 12:00:22 -04003531
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003532 def __init__(self):
3533 curves = iter(get_elliptic_curves())
3534 try:
3535 self.curve_name = next(curves).name
3536 self.another_curve_name = next(curves).name
3537 except StopIteration:
3538 self.curve_name = self.another_curve_name = None
3539
3540
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003541class EllipticCurveEqualityTests(TestCase, EqualityTestsMixin):
3542 """
3543 Tests :py:type:`_EllipticCurve`\ 's implementation of ``==`` and ``!=``.
3544 """
3545 curve_factory = EllipticCurveFactory()
3546
3547 if curve_factory.curve_name is None:
3548 skip = "There are no curves available there can be no curve objects."
3549
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003550 def anInstance(self):
3551 """
3552 Get the curve object for an arbitrary curve supported by the system.
3553 """
3554 return get_elliptic_curve(self.curve_factory.curve_name)
3555
Jean-Paul Calderone1be77082014-04-30 18:17:41 -04003556 def anotherInstance(self):
3557 """
3558 Get the curve object for an arbitrary curve supported by the system -
3559 but not the one returned by C{anInstance}.
3560 """
3561 return get_elliptic_curve(self.curve_factory.another_curve_name)
3562
3563
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003564class EllipticCurveHashTests(TestCase):
3565 """
3566 Tests for :py:type:`_EllipticCurve`\ 's implementation of hashing (thus use
3567 as an item in a :py:type:`dict` or :py:type:`set`).
3568 """
3569 curve_factory = EllipticCurveFactory()
3570
3571 if curve_factory.curve_name is None:
3572 skip = "There are no curves available there can be no curve objects."
3573
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003574 def test_contains(self):
3575 """
3576 The ``in`` operator reports that a :py:type:`set` containing a curve
3577 does contain that curve.
3578 """
3579 curve = get_elliptic_curve(self.curve_factory.curve_name)
3580 curves = set([curve])
3581 self.assertIn(curve, curves)
3582
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003583 def test_does_not_contain(self):
3584 """
3585 The ``in`` operator reports that a :py:type:`set` not containing a
3586 curve does not contain that curve.
3587 """
3588 curve = get_elliptic_curve(self.curve_factory.curve_name)
Alex Gaynor85b49702015-09-05 16:30:59 -04003589 curves = set([
3590 get_elliptic_curve(self.curve_factory.another_curve_name)
3591 ])
Jean-Paul Calderone22c31242014-05-01 07:49:47 -04003592 self.assertNotIn(curve, curves)
3593
3594
Rick Dean5b7b6372009-04-01 11:34:06 -05003595if __name__ == '__main__':
3596 main()