~myers-1/pyopenssl/npn

« back to all changes in this revision

Viewing changes to test/test_crypto.py

  • Committer: Jean-Paul Calderone
  • Date: 2010-01-25 22:55:30 UTC
  • mfrom: (126 trunk)
  • mto: This revision was merged to the branch mainline in revision 129.
  • Revision ID: exarkun@divmod.com-20100125225530-5e9nsb6bzoesoz42
merge trunk and resolve simple conflict

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 
7
7
from unittest import main
8
8
 
 
9
import os, re
9
10
from os import popen2
10
11
from datetime import datetime, timedelta
11
12
 
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
25
26
 
26
27
 
 
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-----
 
46
"""
 
47
 
 
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-----
 
63
"""
 
64
 
 
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-----
 
79
"""
 
80
 
 
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-----
 
96
"""
 
97
 
 
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-----
 
112
"""
 
113
 
 
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-----
 
129
"""
 
130
 
27
131
cleartextCertificatePEM = """-----BEGIN CERTIFICATE-----
28
132
MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
29
133
BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
95
199
"""
96
200
encryptedPrivateKeyPEMPassphrase = "foobar"
97
201
 
98
 
# Some PKCS12 data, base64 encoded.  The data itself was constructed using the
99
 
# openssl command line:
100
 
#
101
 
#    openssl pkcs12 -export -in s.pem -out o.p12 -inkey s.pem -certfile s.pem
102
 
#
103
 
# With s.pem containing a private key and certificate.  The contents of the
104
 
# generated file, o.p12, were then base64 encoded to produce this value.
105
 
pkcs12Data = """\
106
 
MIIJGQIBAzCCCN8GCSqGSIb3DQEHAaCCCNAEggjMMIIIyDCCBucGCSqGSIb3DQEHBqCCBtgwggbU
107
 
AgEAMIIGzQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIdwchN+KDjC8CAggAgIIGoOh59lWQ
108
 
vz7FB2ewPHduY3pBhJX1W7ioN1k2xAoelE04v30CvNNa0A8qIjk6U7WLRXL74jG1xPq+WcAUtNtk
109
 
3ZfTaPTPR+q5xVNBZFHeKDirt7yherl8Xs16OEl0IgNpNHRLeHxi4JeBqkGReq1vkybus2ALyQ/B
110
 
FgbrNJiaGpvUx64A3FnHKbT0pVIvsg5iqcpCQ2SDLeJnqKFuP/2+SE5WnNvM6SBG20HMNOR9+SM5
111
 
tPETapeu7AFkJ03FY3OF+fllHnv8fyXXDkv7F1bX8P2q6wQSRK6DXq6DO1Qjqzmrrtk4Pq6Hne2x
112
 
onN2Bx9yUR83tNn4bQWNDasbnQpdI3Fsgg6RS5+B7y9tw37nygyND9ME0NcCysDov5zIG84gsZHn
113
 
3LDFQkP4M7iBscNCund18FNQomrqAmPvejos+OXMQlNd/la15UQgUqv33V91WIMNmDDt80eVdxp8
114
 
0D4gCvIl3xPp0Lp1EwhXwQxmx7LS3Fj0yCaiBOVevqhp9uq0i5hhdPA4a/XyIAeuJCS07s21fAe3
115
 
Ay3S7olg1DTtN9wSJL6C1wus3VDMicB82ZC4+wAbfheedseenA0ubMDj38JqHgUtb02jMb9Ff3QR
116
 
Hj6qzv5nJIJjmCG+cBatMh775f/9y/7wuElZYjv/vPb9S4Oraxz3ZgLtkU15PVeLjFHsHWRnrhVC
117
 
ORaDEdX42kXfTMTaDsqFPg10ZS4fb7kCqD+ef0U4nCB0pfKyDo3hyDxHxGMqEVwyhKrl2UKljmcz
118
 
02AGKxf6SERGdApGX4ENSuEG8v37CJTnmf1Tvf+K3fcCwBWTVDjhCgyCYrqaR02r8ixjRCU47L7e
119
 
fe0c6WcTIYcXwWPPwqk6lUm8jH/IFSohUxrGaLRsvtYMK5O1ss3fGnv5DysLoWRRHNsp9EqJ+nXP
120
 
bC5KRS01M78twFHXyIVgML13sMwox3aMCADP4HAFisUTQjSq0LlrHHVSIdIz3dEC3jsIs2bRxaVE
121
 
dGaMorvVhoCNucGtdXD778EHsPy6ierUd6LijOYGs+yxUKVdeSAHYiQqBB/0uwo5tqeUjc1xte4V
122
 
7o68M0TnaeXZk6eJj8cy+Z7uvlKrEWG/d+yDp6ZrS/uuCUqlfakSUQVLwhpupRs6bOfbU9VWmuuW
123
 
T/whDpJHkGRqz15d3K43wkF6gWx7tpnwps2boB3fjQVlQ20xJ+4QjYV6Yu/0dlhyU69/sZEHQXvL
124
 
xdZsLwkjEHhGPoMkVSpSZF7mSgM4iI8nFkPbfNOSBGpW8GTYUQN+YI+GjQYwk2zGpB3Fhfc9lVuK
125
 
QqlYUtGkj2UauO9diqS1rVOIQORJ49EmA0w0VJz6A3teklGRQvdfSiTdTmg+PcYtdllquni0MMJO
126
 
3t7fpOnfmZRxvOx9J8WsLlz18uvq8+jDGs0InNFGxUf5v+iTBjY2ByzaMZDa84xqu6+cVuGcQGRu
127
 
NJCpxWNOyfKrDnJ+TOg1/AV3dHiuBNeyOE6XkwzhfEH0TaAWvqtmqRFBIjhsMwkg9qooeJwWANUP
128
 
fq+UxpR8M5UDMBEKcwk+paSLtzAL/Xznk2q9U2JKPrmcD79bSNafDZ33/5U05mGq3CmY5DVjoy+C
129
 
qhbfIQssrNhWxN3yCtHDDOrXVwEb/DAKSIfVz07mRKP/9jW2aC3nmRSt8Gd+JYy4nNRFAcatIcoC
130
 
IHB5rtEXdhHHfZsAaVPGPgfpeVGIK8FXZTSLYGSGHsjXAXG0xS9nXX/8mHyKP3SKd5/h1H9llYhh
131
 
nXXBM7lY6W8A6wRmMmOTkHn5Ovi+mavWeCioKiGfqoUQDRow/PdfwVLUVhe1OTCx4G5F8mXLpIWp
132
 
1wzrOqMfOGDKD+RCgz/5sqVzAvgj0LTttoRKGipJjVb5luaLZswKCtlemD9xRb8J/PRp/6YHvrxW
133
 
2taIJyZPBmbiqXAIFCiwjnurnP9WK4h6ss+bwj8lY3fB8CPwRAyy2p7dpXeNFby0ZkWPlBqKEXgZ
134
 
03uQ8mUGXrty5ha03z7Gzab3RqAUu7l21i4DBbZjcn8j5NPrc3cNVpbJMic/0NDvojI3pIqsQ3yv
135
 
3JbYdkVzlmEmapHCgF/SGVkZMo28uoC1upZMHRvb4zIrRlj1CVlUxmQu00q8GudNBcPOrQVONt5+
136
 
eBvxD/Dco26wHPusPieUMlkj9VP9FS24bdocKXOL7KHOnsZ5oLS1S4hA7l7wEtzfoRHt1M1x8UCQ
137
 
hYcQEbZsOrxqmKlbgm0B6bBsdK0IxGNhgdtKHUCdxHYkpSEYLXwwggHZBgkqhkiG9w0BBwGgggHK
138
 
BIIBxjCCAcIwggG+BgsqhkiG9w0BDAoBAqCCAYYwggGCMBwGCiqGSIb3DQEMAQMwDgQIZ+Y92Rjm
139
 
N5cCAggABIIBYD2z0NOajj7NlnWDRO8hlRiDIo8UTZ3E2UjP4rSbKh7ZLGULHALuH+gcwD3814U7
140
 
VukIkyhiE1VvqPMXb2m4VTCp9BE4oXda0S2Mao1nKxbeMTZ3GE3+C7HPIuTTNQnsnpspIctNAarC
141
 
IIuhgSQmjdILrkmX0QjH5vrQFbdpcDDb/IRba13hws8FM2OrduM+MDEM6xkwiG3AGDgKEPYsd1Ai
142
 
uP8EMX4dzZ9BvEJHaAynzSpUxWy13ntMxNfeIuOKAT9HNsHr0MQgDDpVEhRY26IAZhNFfjtWdAjI
143
 
OiMxk3BjixMUof9i1Xh+4yQsrzLcBJazCyphtb6YvnorQQxWUnaQXWjmU4QS36ajuyOXgFf1Z3jk
144
 
6CLztf6kq3rY4uQ7aQIUJjUcWP0dUGr6LLZRVYP4uL/N/QSasliQGhTxrjEHywyPqRQjKVgV9c6D
145
 
ueHmII59hoZPA6a2cYpQnsuFoeAxJTAjBgkqhkiG9w0BCRUxFgQUVFyHPk/34xv0OdgMn18Sjffj
146
 
7lcwMTAhMAkGBSsOAwIaBQAEFBxVa/flSZttaXvzg+oLJBqgUWuVBAh0s4gPVAEKHAICCAA=
147
 
""".decode('base64')
148
 
 
149
202
# Some PKCS#7 stuff.  Generated with the openssl command line:
150
203
#
151
204
#    openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
915
968
 
916
969
 
917
970
 
 
971
class PKCS12Tests(TestCase):
 
972
    """
 
973
    Test for L{OpenSSL.crypto.PKCS12} and L{OpenSSL.crypto.load_pkcs12}.
 
974
    """
 
975
    pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
 
976
 
 
977
    def test_type(self):
 
978
        """
 
979
        L{PKCS12Type} is a type object.
 
980
        """
 
981
        self.assertIdentical(PKCS12, PKCS12Type)
 
982
        self.assertConsistentType(PKCS12, 'PKCS12')
 
983
 
 
984
 
 
985
    def test_empty_construction(self):
 
986
        """
 
987
        L{PKCS12} returns a new instance of L{PKCS12} with no certificate,
 
988
        private key, CA certificates, or friendly name.
 
989
        """
 
990
        p12 = PKCS12()
 
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())
 
995
 
 
996
 
 
997
    def test_type_errors(self):
 
998
        """
 
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.
 
1002
        """
 
1003
        p12 = PKCS12()
 
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'))
 
1016
 
 
1017
 
 
1018
    def test_key_only(self):
 
1019
        """
 
1020
        A L{PKCS12} with only a private key can be exported using
 
1021
        L{PKCS12.export} and loaded again using L{load_pkcs12}.
 
1022
        """
 
1023
        passwd = 'blah'
 
1024
        p12 = 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())
 
1029
        try:
 
1030
            dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
 
1031
        except Error:
 
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')]
 
1035
            return
 
1036
        p12 = load_pkcs12(dumped_p12, passwd)
 
1037
        self.assertEqual(None, p12.get_ca_certificates())
 
1038
        self.assertEqual(None, p12.get_certificate())
 
1039
 
 
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))))
 
1043
 
 
1044
 
 
1045
    def test_cert_only(self):
 
1046
        """
 
1047
        A L{PKCS12} with only a certificate can be exported using
 
1048
        L{PKCS12.export} and loaded again using L{load_pkcs12}.
 
1049
        """
 
1050
        passwd = 'blah'
 
1051
        p12 = 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())
 
1056
        try:
 
1057
            dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
 
1058
        except Error:
 
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')]
 
1062
            return
 
1063
        p12 = load_pkcs12(dumped_p12, passwd)
 
1064
        self.assertEqual(None, p12.get_privatekey())
 
1065
 
 
1066
        # OpenSSL fails to bring the cert back to us.  Groany mcgroan.
 
1067
        self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
 
1068
 
 
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
 
1074
        # certificate.
 
1075
        self.assertEqual(
 
1076
            cleartextCertificatePEM,
 
1077
            dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
 
1078
 
 
1079
 
 
1080
    def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None):
 
1081
        """
 
1082
        Generate a PKCS12 object with components from PEM.  Verify that the set
 
1083
        functions return None.
 
1084
        """
 
1085
        p12 = PKCS12()
 
1086
        if cert_pem:
 
1087
            ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
 
1088
            self.assertEqual(ret, None)
 
1089
        if key_pem:
 
1090
            ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
 
1091
            self.assertEqual(ret, None)
 
1092
        if ca_pem:
 
1093
            ret = p12.set_ca_certificates((load_certificate(FILETYPE_PEM, ca_pem),))
 
1094
            self.assertEqual(ret, None)
 
1095
        if friendly_name:
 
1096
            ret = p12.set_friendlyname(friendly_name)
 
1097
            self.assertEqual(ret, None)
 
1098
        return p12
 
1099
 
 
1100
 
 
1101
    def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd='',
 
1102
                       extra=()):
 
1103
        """
 
1104
        Use openssl program to confirm three components are recoverable from a
 
1105
        PKCS12 string.
 
1106
        """
 
1107
        if key:
 
1108
            recovered_key = _runopenssl(
 
1109
                p12_str, "pkcs12", '-nocerts', '-nodes', '-passin',
 
1110
                'pass:' + passwd, *extra)
 
1111
            self.assertEqual(recovered_key[-len(key):], key)
 
1112
        if cert:
 
1113
            recovered_cert = _runopenssl(
 
1114
                p12_str, "pkcs12", '-clcerts', '-nodes', '-passin',
 
1115
                'pass:' + passwd, '-nokeys', *extra)
 
1116
            self.assertEqual(recovered_cert[-len(cert):], cert)
 
1117
        if ca:
 
1118
            recovered_cert = _runopenssl(
 
1119
                p12_str, "pkcs12", '-cacerts', '-nodes', '-passin',
 
1120
                'pass:' + passwd, '-nokeys', *extra)
 
1121
            self.assertEqual(recovered_cert[-len(ca):], ca)
 
1122
 
 
1123
 
 
1124
    def test_load_pkcs12(self):
 
1125
        """
 
1126
        A PKCS12 string generated using the openssl command line can be loaded
 
1127
        with L{load_pkcs12} and its components extracted and examined.
 
1128
        """
 
1129
        passwd = 'whatever'
 
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)
 
1134
        # verify
 
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())
 
1141
 
 
1142
 
 
1143
    def test_load_pkcs12_garbage(self):
 
1144
        """
 
1145
        L{load_pkcs12} raises L{OpenSSL.crypto.Error} when passed a string
 
1146
        which is not a PKCS12 dump.
 
1147
        """
 
1148
        passwd = 'whatever'
 
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)
 
1152
 
 
1153
 
 
1154
    def test_replace(self):
 
1155
        """
 
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.
 
1159
        """
 
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])
 
1172
 
 
1173
 
 
1174
    def test_friendly_name(self):
 
1175
        """
 
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}.
 
1179
        """
 
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)
 
1187
            self.assertEqual(
 
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)
 
1196
 
 
1197
 
 
1198
    def test_various_empty_passphrases(self):
 
1199
        """
 
1200
        Test that missing, None, and '' passphrases are identical for PKCS12
 
1201
        export.
 
1202
        """
 
1203
        p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
 
1204
        passwd = ''
 
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)
 
1212
 
 
1213
 
 
1214
    def test_removing_ca_cert(self):
 
1215
        """
 
1216
        Passing C{None} to L{PKCS12.set_ca_certificates} removes all CA
 
1217
        certificates.
 
1218
        """
 
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())
 
1222
 
 
1223
 
 
1224
    def test_export_without_mac(self):
 
1225
        """
 
1226
        Exporting a PKCS12 with a C{maciter} of C{-1} excludes the MAC
 
1227
        entirely.
 
1228
        """
 
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',))
 
1235
 
 
1236
 
 
1237
    def test_load_without_mac(self):
 
1238
        """
 
1239
        Loading a PKCS12 without a MAC does something other than crash.
 
1240
        """
 
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)
 
1244
        try:
 
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))
 
1252
        except Error:
 
1253
            # Failing here with an exception is preferred as some openssl
 
1254
            # versions do.
 
1255
            pass
 
1256
 
 
1257
 
 
1258
    def test_zero_len_list_for_ca(self):
 
1259
        """
 
1260
        A PKCS12 with an empty CA certificates list can be exported.
 
1261
        """
 
1262
        passwd = 'Hobie 18'
 
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,
 
1269
            passwd=passwd)
 
1270
 
 
1271
 
 
1272
    def test_export_without_args(self):
 
1273
        """
 
1274
        All the arguments to L{PKCS12.export} are optional.
 
1275
        """
 
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='')
 
1280
 
 
1281
 
 
1282
    def test_key_cert_mismatch(self):
 
1283
        """
 
1284
        L{PKCS12.export} raises an exception when a key and certificate
 
1285
        mismatch.
 
1286
        """
 
1287
        p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
 
1288
        self.assertRaises(Error, p12.export)
 
1289
 
 
1290
 
 
1291
 
 
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):
 
1296
    """
 
1297
    Internal method for quoting a single command-line argument.
 
1298
 
 
1299
    @type: C{str}
 
1300
    @param s: A single unquoted string to quote for something that is expecting
 
1301
        cmd.exe-style quoting
 
1302
 
 
1303
    @rtype: C{str}
 
1304
    @return: A cmd.exe-style quoted string
 
1305
 
 
1306
    @see: U{http://www.perlmonks.org/?node_id=764004}
 
1307
    """
 
1308
    s = _cmdLineQuoteRe2.sub(r"\1\1", _cmdLineQuoteRe.sub(r'\1\1\\"', s))
 
1309
    return '"%s"' % s
 
1310
 
 
1311
 
 
1312
 
 
1313
def quoteArguments(arguments):
 
1314
    """
 
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.
 
1318
 
 
1319
    @type arguments: C{iterable} of C{str}
 
1320
    @param arguments: An iterable of unquoted arguments to quote
 
1321
 
 
1322
    @rtype: C{str}
 
1323
    @return: A space-delimited string containing quoted versions of L{arguments}
 
1324
    """
 
1325
    return ' '.join(map(cmdLineQuote, arguments))
 
1326
 
 
1327
 
 
1328
def _runopenssl(pem, *args):
 
1329
    """
 
1330
    Run the command line openssl tool with the given arguments and write
 
1331
    the given PEM to its stdin.  Not safe for quotes.
 
1332
    """
 
1333
    if os.name == 'posix':
 
1334
        command = "openssl " + " ".join(["'%s'" % (arg.replace("'", "'\\''"),) for arg in args])
 
1335
    else:
 
1336
        command = "openssl " + quoteArguments(args)
 
1337
    write, read = popen2(command, "b")
 
1338
    write.write(pem)
 
1339
    write.close()
 
1340
    return read.read()
 
1341
 
 
1342
 
 
1343
 
918
1344
class FunctionTests(TestCase):
919
1345
    """
920
1346
    Tests for free-functions in the L{OpenSSL.crypto} module.
984
1410
        self.assertEqual(loadedKey.bits(), key.bits())
985
1411
 
986
1412
 
987
 
    def _runopenssl(self, pem, *args):
988
 
        """
989
 
        Run the command line openssl tool with the given arguments and write
990
 
        the given PEM to its stdin.
991
 
        """
992
 
        write, read = popen2(" ".join(("openssl",) + args), "b")
993
 
        write.write(pem)
994
 
        write.close()
995
 
        return read.read()
996
 
 
997
 
 
998
1413
    def test_dump_certificate(self):
999
1414
        """
1000
1415
        L{dump_certificate} writes PEM, DER, and text.
1004
1419
        dumped_pem = dump_certificate(FILETYPE_PEM, cert)
1005
1420
        self.assertEqual(dumped_pem, cleartextCertificatePEM)
1006
1421
        dumped_der = dump_certificate(FILETYPE_ASN1, cert)
1007
 
        good_der = self._runopenssl(dumped_pem, "x509", "-outform", "DER")
 
1422
        good_der = _runopenssl(dumped_pem, "x509", "-outform", "DER")
1008
1423
        self.assertEqual(dumped_der, good_der)
1009
1424
        cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
1010
1425
        dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
1011
1426
        self.assertEqual(dumped_pem2, cleartextCertificatePEM)
1012
1427
        dumped_text = dump_certificate(FILETYPE_TEXT, cert)
1013
 
        good_text = self._runopenssl(dumped_pem, "x509", "-noout", "-text")
 
1428
        good_text = _runopenssl(dumped_pem, "x509", "-noout", "-text")
1014
1429
        self.assertEqual(dumped_text, good_text)
1015
1430
 
1016
1431
 
1023
1438
        self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
1024
1439
        dumped_der = dump_privatekey(FILETYPE_ASN1, key)
1025
1440
        # XXX This OpenSSL call writes "writing RSA key" to standard out.  Sad.
1026
 
        good_der = self._runopenssl(dumped_pem, "rsa", "-outform", "DER")
 
1441
        good_der = _runopenssl(dumped_pem, "rsa", "-outform", "DER")
1027
1442
        self.assertEqual(dumped_der, good_der)
1028
1443
        key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
1029
1444
        dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
1030
1445
        self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
1031
1446
        dumped_text = dump_privatekey(FILETYPE_TEXT, key)
1032
 
        good_text = self._runopenssl(dumped_pem, "rsa", "-noout", "-text")
 
1447
        good_text = _runopenssl(dumped_pem, "rsa", "-noout", "-text")
1033
1448
        self.assertEqual(dumped_text, good_text)
1034
1449
 
1035
1450
 
1041
1456
        dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
1042
1457
        self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
1043
1458
        dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
1044
 
        good_der = self._runopenssl(dumped_pem, "req", "-outform", "DER")
 
1459
        good_der = _runopenssl(dumped_pem, "req", "-outform", "DER")
1045
1460
        self.assertEqual(dumped_der, good_der)
1046
1461
        req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
1047
1462
        dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
1048
1463
        self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
1049
1464
        dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
1050
 
        good_text = self._runopenssl(dumped_pem, "req", "-noout", "-text")
 
1465
        good_text = _runopenssl(dumped_pem, "req", "-noout", "-text")
1051
1466
        self.assertEqual(dumped_text, good_text)
1052
1467
 
1053
1468
 
1080
1495
        self.assertTrue(isinstance(pkcs7, PKCS7Type))
1081
1496
 
1082
1497
 
1083
 
    def test_load_pkcs12(self):
1084
 
        """
1085
 
        L{load_pkcs12} accepts a PKCS#12 string and returns an instance of
1086
 
        L{PKCS12Type}.
1087
 
        """
1088
 
        pkcs12 = load_pkcs12(pkcs12Data)
1089
 
        self.assertTrue(isinstance(pkcs12, PKCS12Type))
1090
 
 
1091
 
 
1092
1498
 
1093
1499
class PKCS7Tests(TestCase):
1094
1500
    """
1106
1512
 
1107
1513
 
1108
1514
 
1109
 
class PKCS12Tests(TestCase):
1110
 
    """
1111
 
    Tests for L{PKCS12Type}.
1112
 
    """
1113
 
    def test_type(self):
1114
 
        """
1115
 
        L{PKCS12Type} is a type object.
1116
 
        """
1117
 
        self.assertTrue(isinstance(PKCS12Type, type))
1118
 
        self.assertEqual(PKCS12Type.__name__, 'PKCS12')
1119
 
 
1120
 
        # XXX This doesn't currently work.
1121
 
        # self.assertIdentical(PKCS12, PKCS12Type)
1122
 
 
1123
 
 
1124
 
 
1125
1515
class NetscapeSPKITests(TestCase):
1126
1516
    """
1127
1517
    Tests for L{OpenSSL.crypto.NetscapeSPKI}.