18
19
from OpenSSL.crypto import dump_certificate, load_certificate_request
19
20
from OpenSSL.crypto import dump_certificate_request, dump_privatekey
20
21
from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
21
from OpenSSL.crypto import PKCS12Type, load_pkcs12
22
from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
22
23
from OpenSSL.crypto import CRL, Revoked, load_crl
23
24
from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
24
25
from OpenSSL.test.util import TestCase
28
root_cert_pem = """-----BEGIN CERTIFICATE-----
29
MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
30
BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
31
ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
32
NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
33
MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
34
ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
35
urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
36
2xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
37
1dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
38
FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
39
VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
40
BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
41
b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
42
AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
43
hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
44
w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
45
-----END CERTIFICATE-----
48
root_key_pem = """-----BEGIN RSA PRIVATE KEY-----
49
MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
50
jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
51
3claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
52
AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
53
yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
54
6JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
55
BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
56
u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
57
PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
58
I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
59
ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
60
6AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
61
cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
62
-----END RSA PRIVATE KEY-----
65
server_cert_pem = """-----BEGIN CERTIFICATE-----
66
MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
67
BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
68
VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
69
NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
70
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
71
lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
72
b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
73
lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
74
gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
75
dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
76
2mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
77
uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
78
-----END CERTIFICATE-----
81
server_key_pem = """-----BEGIN RSA PRIVATE KEY-----
82
MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
83
U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
84
SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
85
AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
86
j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
87
j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
88
Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
89
msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
90
FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
91
4e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
92
1sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
93
NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
94
r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
95
-----END RSA PRIVATE KEY-----
98
client_cert_pem = """-----BEGIN CERTIFICATE-----
99
MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
100
BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
101
VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
102
ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
103
MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
104
rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
105
iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
106
oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
107
0fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
108
Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
109
9Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
110
PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
111
-----END CERTIFICATE-----
114
client_key_pem = """-----BEGIN RSA PRIVATE KEY-----
115
MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
116
btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
117
eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
118
AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
119
zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
120
h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
121
V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
122
TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
123
dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
124
D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
125
si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
126
JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
127
f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
128
-----END RSA PRIVATE KEY-----
27
131
cleartextCertificatePEM = """-----BEGIN CERTIFICATE-----
28
132
MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
29
133
BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
971
class PKCS12Tests(TestCase):
973
Test for L{OpenSSL.crypto.PKCS12} and L{OpenSSL.crypto.load_pkcs12}.
975
pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
979
L{PKCS12Type} is a type object.
981
self.assertIdentical(PKCS12, PKCS12Type)
982
self.assertConsistentType(PKCS12, 'PKCS12')
985
def test_empty_construction(self):
987
L{PKCS12} returns a new instance of L{PKCS12} with no certificate,
988
private key, CA certificates, or friendly name.
991
self.assertEqual(None, p12.get_certificate())
992
self.assertEqual(None, p12.get_privatekey())
993
self.assertEqual(None, p12.get_ca_certificates())
994
self.assertEqual(None, p12.get_friendlyname())
997
def test_type_errors(self):
999
The L{PKCS12} setter functions (C{set_certificate}, C{set_privatekey},
1000
C{set_ca_certificates}, and C{set_friendlyname}) raise L{TypeError}
1001
when passed objects of types other than those expected.
1004
self.assertRaises(TypeError, p12.set_certificate, 3)
1005
self.assertRaises(TypeError, p12.set_certificate, PKey())
1006
self.assertRaises(TypeError, p12.set_certificate, X509)
1007
self.assertRaises(TypeError, p12.set_privatekey, 3)
1008
self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1009
self.assertRaises(TypeError, p12.set_privatekey, X509())
1010
self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1011
self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1012
self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
1013
self.assertRaises(TypeError, p12.set_ca_certificates, ( PKey(), ))
1014
self.assertRaises(TypeError, p12.set_friendlyname, 6)
1015
self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
1018
def test_key_only(self):
1020
A L{PKCS12} with only a private key can be exported using
1021
L{PKCS12.export} and loaded again using L{load_pkcs12}.
1025
pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
1026
p12.set_privatekey(pkey)
1027
self.assertEqual(None, p12.get_certificate())
1028
self.assertEqual(pkey, p12.get_privatekey())
1030
dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1032
# Some versions of OpenSSL will throw an exception
1033
# for this nearly useless PKCS12 we tried to generate:
1034
# [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1036
p12 = load_pkcs12(dumped_p12, passwd)
1037
self.assertEqual(None, p12.get_ca_certificates())
1038
self.assertEqual(None, p12.get_certificate())
1040
# OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1041
# future this will be improved.
1042
self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
1045
def test_cert_only(self):
1047
A L{PKCS12} with only a certificate can be exported using
1048
L{PKCS12.export} and loaded again using L{load_pkcs12}.
1052
cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1053
p12.set_certificate(cert)
1054
self.assertEqual(cert, p12.get_certificate())
1055
self.assertEqual(None, p12.get_privatekey())
1057
dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1059
# Some versions of OpenSSL will throw an exception
1060
# for this nearly useless PKCS12 we tried to generate:
1061
# [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1063
p12 = load_pkcs12(dumped_p12, passwd)
1064
self.assertEqual(None, p12.get_privatekey())
1066
# OpenSSL fails to bring the cert back to us. Groany mcgroan.
1067
self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1069
# Oh ho. It puts the certificate into the ca certificates list, in
1070
# fact. Totally bogus, I would think. Nevertheless, let's exploit
1071
# that to check to see if it reconstructed the certificate we expected
1072
# it to. At some point, hopefully this will change so that
1073
# p12.get_certificate() is actually what returns the loaded
1076
cleartextCertificatePEM,
1077
dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
1080
def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None):
1082
Generate a PKCS12 object with components from PEM. Verify that the set
1083
functions return None.
1087
ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1088
self.assertEqual(ret, None)
1090
ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
1091
self.assertEqual(ret, None)
1093
ret = p12.set_ca_certificates((load_certificate(FILETYPE_PEM, ca_pem),))
1094
self.assertEqual(ret, None)
1096
ret = p12.set_friendlyname(friendly_name)
1097
self.assertEqual(ret, None)
1101
def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd='',
1104
Use openssl program to confirm three components are recoverable from a
1108
recovered_key = _runopenssl(
1109
p12_str, "pkcs12", '-nocerts', '-nodes', '-passin',
1110
'pass:' + passwd, *extra)
1111
self.assertEqual(recovered_key[-len(key):], key)
1113
recovered_cert = _runopenssl(
1114
p12_str, "pkcs12", '-clcerts', '-nodes', '-passin',
1115
'pass:' + passwd, '-nokeys', *extra)
1116
self.assertEqual(recovered_cert[-len(cert):], cert)
1118
recovered_cert = _runopenssl(
1119
p12_str, "pkcs12", '-cacerts', '-nodes', '-passin',
1120
'pass:' + passwd, '-nokeys', *extra)
1121
self.assertEqual(recovered_cert[-len(ca):], ca)
1124
def test_load_pkcs12(self):
1126
A PKCS12 string generated using the openssl command line can be loaded
1127
with L{load_pkcs12} and its components extracted and examined.
1130
pem = client_key_pem + client_cert_pem
1131
p12_str = _runopenssl(
1132
pem, "pkcs12", '-export', '-clcerts', '-passout', 'pass:' + passwd)
1133
p12 = load_pkcs12(p12_str, passwd)
1135
self.assertTrue(isinstance(p12, PKCS12))
1136
cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
1137
self.assertEqual(cert_pem, client_cert_pem)
1138
key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
1139
self.assertEqual(key_pem, client_key_pem)
1140
self.assertEqual(None, p12.get_ca_certificates())
1143
def test_load_pkcs12_garbage(self):
1145
L{load_pkcs12} raises L{OpenSSL.crypto.Error} when passed a string
1146
which is not a PKCS12 dump.
1149
e = self.assertRaises(Error, load_pkcs12, 'fruit loops', passwd)
1150
self.assertEqual( e[0][0][0], 'asn1 encoding routines')
1151
self.assertEqual( len(e[0][0]), 3)
1154
def test_replace(self):
1156
L{PKCS12.set_certificate} replaces the certificate in a PKCS12 cluster.
1157
L{PKCS12.set_privatekey} replaces the private key.
1158
L{PKCS12.set_ca_certificates} replaces the CA certificates.
1160
p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
1161
p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1162
p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1163
root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1164
client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
1165
p12.set_ca_certificates([root_cert]) # not a tuple
1166
self.assertEqual(1, len(p12.get_ca_certificates()))
1167
self.assertEqual(root_cert, p12.get_ca_certificates()[0])
1168
p12.set_ca_certificates([client_cert, root_cert])
1169
self.assertEqual(2, len(p12.get_ca_certificates()))
1170
self.assertEqual(client_cert, p12.get_ca_certificates()[0])
1171
self.assertEqual(root_cert, p12.get_ca_certificates()[1])
1174
def test_friendly_name(self):
1176
The I{friendlyName} of a PKCS12 can be set and retrieved via
1177
L{PKCS12.get_friendlyname} and L{PKCS12_set_friendlyname}, and a
1178
L{PKCS12} with a friendly name set can be dumped with L{PKCS12.export}.
1180
passwd = 'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
1181
p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1182
for friendly_name in ['Serverlicious', None, '###']:
1183
p12.set_friendlyname(friendly_name)
1184
self.assertEqual(p12.get_friendlyname(), friendly_name)
1185
dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1186
reloaded_p12 = load_pkcs12(dumped_p12, passwd)
1188
p12.get_friendlyname(),reloaded_p12.get_friendlyname())
1189
# We would use the openssl program to confirm the friendly
1190
# name, but it is not possible. The pkcs12 command
1191
# does not store the friendly name in the cert's
1192
# alias, which we could then extract.
1193
self.check_recovery(
1194
dumped_p12, key=server_key_pem, cert=server_cert_pem,
1195
ca=root_cert_pem, passwd=passwd)
1198
def test_various_empty_passphrases(self):
1200
Test that missing, None, and '' passphrases are identical for PKCS12
1203
p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
1205
dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
1206
dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
1207
dumped_p12_nopw = p12.export(iter=9, maciter=4)
1208
for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
1209
self.check_recovery(
1210
dumped_p12, key=client_key_pem, cert=client_cert_pem,
1211
ca=root_cert_pem, passwd=passwd)
1214
def test_removing_ca_cert(self):
1216
Passing C{None} to L{PKCS12.set_ca_certificates} removes all CA
1219
p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1220
p12.set_ca_certificates(None)
1221
self.assertEqual(None, p12.get_ca_certificates())
1224
def test_export_without_mac(self):
1226
Exporting a PKCS12 with a C{maciter} of C{-1} excludes the MAC
1229
passwd = 'Lake Michigan'
1230
p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1231
dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
1232
self.check_recovery(
1233
dumped_p12, key=server_key_pem, cert=server_cert_pem,
1234
passwd=passwd, extra=('-nomacver',))
1237
def test_load_without_mac(self):
1239
Loading a PKCS12 without a MAC does something other than crash.
1241
passwd = 'Lake Michigan'
1242
p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1243
dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
1245
recovered_p12 = load_pkcs12(dumped_p12, passwd)
1246
# The person who generated this PCKS12 should be flogged,
1247
# or better yet we should have a means to determine
1248
# whether a PCKS12 had a MAC that was verified.
1249
# Anyway, libopenssl chooses to allow it, so the
1250
# pyopenssl binding does as well.
1251
self.assertTrue(isinstance(recovered_p12, PKCS12))
1253
# Failing here with an exception is preferred as some openssl
1258
def test_zero_len_list_for_ca(self):
1260
A PKCS12 with an empty CA certificates list can be exported.
1263
p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
1264
p12.set_ca_certificates([])
1265
self.assertEqual((), p12.get_ca_certificates())
1266
dumped_p12 = p12.export(passphrase=passwd, iter=3)
1267
self.check_recovery(
1268
dumped_p12, key=server_key_pem, cert=server_cert_pem,
1272
def test_export_without_args(self):
1274
All the arguments to L{PKCS12.export} are optional.
1276
p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1277
dumped_p12 = p12.export() # no args
1278
self.check_recovery(
1279
dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd='')
1282
def test_key_cert_mismatch(self):
1284
L{PKCS12.export} raises an exception when a key and certificate
1287
p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
1288
self.assertRaises(Error, p12.export)
1292
# These quoting functions taken directly from Twisted's twisted.python.win32.
1293
_cmdLineQuoteRe = re.compile(r'(\\*)"')
1294
_cmdLineQuoteRe2 = re.compile(r'(\\+)\Z')
1295
def cmdLineQuote(s):
1297
Internal method for quoting a single command-line argument.
1300
@param s: A single unquoted string to quote for something that is expecting
1301
cmd.exe-style quoting
1304
@return: A cmd.exe-style quoted string
1306
@see: U{http://www.perlmonks.org/?node_id=764004}
1308
s = _cmdLineQuoteRe2.sub(r"\1\1", _cmdLineQuoteRe.sub(r'\1\1\\"', s))
1313
def quoteArguments(arguments):
1315
Quote an iterable of command-line arguments for passing to CreateProcess or
1316
a similar API. This allows the list passed to C{reactor.spawnProcess} to
1317
match the child process's C{sys.argv} properly.
1319
@type arguments: C{iterable} of C{str}
1320
@param arguments: An iterable of unquoted arguments to quote
1323
@return: A space-delimited string containing quoted versions of L{arguments}
1325
return ' '.join(map(cmdLineQuote, arguments))
1328
def _runopenssl(pem, *args):
1330
Run the command line openssl tool with the given arguments and write
1331
the given PEM to its stdin. Not safe for quotes.
1333
if os.name == 'posix':
1334
command = "openssl " + " ".join(["'%s'" % (arg.replace("'", "'\\''"),) for arg in args])
1336
command = "openssl " + quoteArguments(args)
1337
write, read = popen2(command, "b")
918
1344
class FunctionTests(TestCase):
920
1346
Tests for free-functions in the L{OpenSSL.crypto} module.