#!/usr/bin/python

import sys
import os
import os.path
import getopt
import subprocess


cabundle_pem = '''# TERENA SSL CA 3
-----BEGIN CERTIFICATE-----
MIIE+zCCA+OgAwIBAgIQCHC8xa8/25Wakctq7u/kZTANBgkqhkiG9w0BAQsFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
b3QgQ0EwHhcNMTQxMTE4MTIwMDAwWhcNMjQxMTE4MTIwMDAwWjBkMQswCQYDVQQG
EwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJQW1zdGVyZGFt
MQ8wDQYDVQQKEwZURVJFTkExGDAWBgNVBAMTD1RFUkVOQSBTU0wgQ0EgMzCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMV2Dw/ZQyk7bG3RR63eEL8jwnio
Snc18SNb4EweQefCMQC9iDdFdd25AhCAHo/tZCMERaegOTuBTc9jP8JJ/yKeiLDS
lrlcinQfkioq8hLIt2hUtVhBgUBoBhpPhSn7tU08D08/QJYbzqjMXjX/ZJj1dd10
VAWgNhEEEiRVY++Udy538RV27tOkWUUhn6i+0SftCuirOMo/h9Ha8Y+5Cx9E5+Ct
85XCFk3shKM6ktTPxn3mvcsaQE+zVLHzj28NHuO+SaNW5Ae8jafOHbBbV1bRxBz8
mGXRzUYvkZS/RYVJ+G1ShxwCVgEnFqtyLvRx5GG1IKD6JmlqCvGrn223zyUCAwEA
AaOCAaYwggGiMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMHkG
CCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
Y29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
aUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRw
Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3Js
MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk
SURSb290Q0EuY3JsMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxo
dHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBRn/YggFCeYxwnS
JRm76VERY3VQYjAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
hkiG9w0BAQsFAAOCAQEAqSg1esR71tonHqyYzyc2TxEydHTmQN0dzfJodzWvs4xd
xgS/FfQjZ4u5b5cE60adws3J0aSugS7JurHogNAcyTnBVnZZbJx946nw09E02DxJ
WYsamM6/xvLYMDX/6W9doK867mZTrqqMaci+mqege9iCSzMTyAfzd9fzZM2eY/lC
J1OuEDOJcjcV8b73HjWizsMt8tey5gvHacDlH198aZt+ziYaM0TDuncFO7pdP0GJ
+hY77gRuW6xWS++McPJKe1e9GW6LNgdUJi2GCZQfXzer8CM/jyxflp5HcahE3qm5
hS+1NGClXwmgmkMd1L8tRNaN2v11y18WoA5hwnA9Ng==
-----END CERTIFICATE-----
# DigiCert Assured ID Root CA
-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
-----END CERTIFICATE-----
'''


infncert = '''MIIFPzCCBCegAwIBAgIQDMAknpWXh0Fm32nLxLQATDANBgkqhkiG9w0BAQsFADBk
MQswCQYDVQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJ
QW1zdGVyZGFtMQ8wDQYDVQQKEwZURVJFTkExGDAWBgNVBAMTD1RFUkVOQSBTU0wg
Q0EgMzAeFw0xODAxMjIwMDAwMDBaFw0yMTAxMjYxMjAwMDBaMH8xCzAJBgNVBAYT
AklUMREwDwYDVQQHEwhGcmFzY2F0aTEuMCwGA1UEChMlSXN0aXR1dG8gTmF6aW9u
YWxlIGRpIEZpc2ljYSBOdWNsZWFyZTELMAkGA1UECxMCcGQxIDAeBgNVBAMTF2Ns
b3VkLWFyZWFwZC5wZC5pbmZuLml0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAvpZqWzHR5Jl2+T8C55R7yIolFWTC2qsHDIFkm9lzHVmPxRxflPKwTR/M
YDNiYPYC68NBE3rPHwEqm/9ynt8Fzvvnz7ZPvcuMSKBmXrn74Bq/PC/RnjxAcdvm
Uoi+emjW0q3h7Ecm2EjRiFtlvrFXgMSby8T54Bh2Zwe41xmZWgAHllcCjKi5TS8T
AHpmugZImBEHunHKrpVqJvjHJ48P4t6zaxDEJFK1F74mUYS0EC0T+E9XHNqsQWJa
x3OYi5oBK0WqxNZrNk6QvIveoTOgIkwkdCnyVEq3RK0OGERlAL9XEgn2CQ2GMX8h
YhYVKryMCd4+SYOS/b/Rk/iCcn+q3wIDAQABo4IB0DCCAcwwHwYDVR0jBBgwFoAU
Z/2IIBQnmMcJ0iUZu+lREWN1UGIwHQYDVR0OBBYEFEwAJC0rQFw7Kf6J4lLqKtZD
e1flMCIGA1UdEQQbMBmCF2Nsb3VkLWFyZWFwZC5wZC5pbmZuLml0MA4GA1UdDwEB
/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYDVR0fBGQw
YjAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL1RFUkVOQVNTTENBMy5j
cmwwL6AtoCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9URVJFTkFTU0xDQTMu
Y3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBz
Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMG4GCCsGAQUFBwEBBGIw
YDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMDgGCCsGAQUF
BzAChixodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vVEVSRU5BU1NMQ0EzLmNy
dDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAdsZCWSVZySYV7wgs4
sMgQas4u1zqGXiNkG2yWCSZpymhuKUi2rc+ODbVcByPYzRPeF+bs5vwu60pZ2BUU
DA8q27ewj5wWo2j+GrVS/dZJkqwmwPfe494BB/E024ZZ69hxEVYZ4OT1a2NtrOwO
4nRgTW8beMeCSKXeZ6vkTx+QG6mshDwtf351xdUkwv36mNEqKnGXHwvBINbjPwdZ
uFSGwIe9Imk5rvkTSi25qxVeWaIprMdRyQi0ghmgiKY61G3kdcrbp65GN4CNLLMK
y2HwCbHNqVKfqicYDgXc6Z2DGVfI9uQyWADYNdND+mz73OVnZMdKjkd1WyNFd3GX
iE43'''

infntestcert = '''MIIFSjCCBDKgAwIBAgIQCIJXBpFnoiVSdK265GcX8zANBgkqhkiG9w0BAQsFADBk
MQswCQYDVQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJ
QW1zdGVyZGFtMQ8wDQYDVQQKEwZURVJFTkExGDAWBgNVBAMTD1RFUkVOQSBTU0wg
Q0EgMzAeFw0xODAxMjIwMDAwMDBaFw0yMTAxMjYxMjAwMDBaMIGEMQswCQYDVQQG
EwJJVDERMA8GA1UEBxMIRnJhc2NhdGkxLjAsBgNVBAoTJUlzdGl0dXRvIE5hemlv
bmFsZSBkaSBGaXNpY2EgTnVjbGVhcmUxCzAJBgNVBAsTAnBkMSUwIwYDVQQDExxj
bG91ZC1hcmVhcGQtdGVzdC5wZC5pbmZuLml0MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA5TC2eBSUJ5oSy98IayKPRyTWjvEMrhZUXTbl/A0tA/B7/Z9K
RrBrOEklfiPo8RfkenRYbboUpka+EnxprsCMXYyNMD0Td1yApNtiZiXxBV1+chQG
kKXKtgShzXX+qrrd2VWST/7gf8Y2s1B2DoTLye6iRYwfs5X1CXngSC9/L5bb/K+f
8yAEdHRosATNa20+CDso6mCXTcpenSypLJ8Be7zaBduXKBnbxQxH/nQcuYVf21wT
KyeJTos0lI47JnOcVq3yxgJvSELITTt8rWuy+BpjFzAkLs34vfkVXvWFqInRMRsa
hA92ndegM8KdO2bPirq8GbdRgcGvmAXKAKmVFQIDAQABo4IB1TCCAdEwHwYDVR0j
BBgwFoAUZ/2IIBQnmMcJ0iUZu+lREWN1UGIwHQYDVR0OBBYEFN+by0EtjPE/gek4
s83B0iJUnX7NMCcGA1UdEQQgMB6CHGNsb3VkLWFyZWFwZC10ZXN0LnBkLmluZm4u
aXQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
AjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vVEVS
RU5BU1NMQ0EzLmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL1RF
UkVOQVNTTENBMy5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEF
BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwbgYI
KwYBBQUHAQEEYjBgMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
b20wOAYIKwYBBQUHMAKGLGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9URVJF
TkFTU0xDQTMuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBABMU
7UnweUILNMeA2DAci04ety6e3Ybu96LEOPSfmnqSwQJI7ABei/yRkgIPBg1sRwHC
l1Ek2ZQ1cPhibkzESkHhqKM9EioNUBxyBWmL+e97hP/KKJF9ksDYlNDnwhb6RYUW
WIwksYaT5+Wf3+w8D7apeVjlF44VDq9usIZWnZn3F7F/x7cjvgtLzbYyC5mcZugX
F2qSXUOrHMb7SxDrRIrtDGplijnWWUvMeRkYK/VU0wy6aP8niNjwFt4RGmQE7ZKZ
LjtyKMySlj0NoHOmih5U3FAVYW0gTkEuivT1Fevc+8PpgXw2VSBUqP6lQpAYounP
KADmPLerXOA3xv4H5YE='''

unipdcert = '''MIIGvTCCBaWgAwIBAgIQDHCWyUfbV3zwC82tHuCyIjANBgkqhkiG9w0BAQsFADBk
MQswCQYDVQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJ
QW1zdGVyZGFtMQ8wDQYDVQQKEwZURVJFTkExGDAWBgNVBAMTD1RFUkVOQSBTU0wg
Q0EgMzAeFw0xODAyMDUwMDAwMDBaFw0yMDAyMTAxMjAwMDBaMHsxCzAJBgNVBAYT
AklUMQ8wDQYDVQQHEwZQYWRvdmExKjAoBgNVBAoMIVVuaXZlcnNpdMOgIGRlZ2xp
IFN0dWRpIGRpIFBhZG92YTEMMAoGA1UECxMDSUNUMSEwHwYDVQQDExhjbG91ZHZl
bmV0by5pY3QudW5pcGQuaXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCvy+SregvnYuFhCq1kYDGjGfpA5dtwoqPS9E2o9R35IlrAGr/NgTWhGs7w/7uw
iEKR0cryS1/enCuseSDmew+3gGCOjuR7XD+If4EAL32mNaRAajL5ef4XbsrMk/V3
QBShxu4/CW8LOhD1IrH39iVirbKopA3PrVVc2WrJvwcDizPV4hRZvTW9hfGWJcXN
6GZ2Y3AST+Q6RgVlmrB3ThH9dR95JBC8tby7s/8mNfnhWKoCirgCBirUErF5STIY
Sl79if3A+fnUbEuu9210EStgNvYRUKBDt4Fg2+ksxWv++A61x236csBXL/2zaHtj
G8erzOs59p0PDhATjRwcVi6JAgMBAAGjggNSMIIDTjAfBgNVHSMEGDAWgBRn/Ygg
FCeYxwnSJRm76VERY3VQYjAdBgNVHQ4EFgQUwYRvuBcJy0QR6DF8917pdFYMCgEw
IwYDVR0RBBwwGoIYY2xvdWR2ZW5ldG8uaWN0LnVuaXBkLml0MA4GA1UdDwEB/wQE
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYDVR0fBGQwYjAv
oC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL1RFUkVOQVNTTENBMy5jcmww
L6AtoCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9URVJFTkFTU0xDQTMuY3Js
MEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMG4GCCsGAQUFBwEBBGIwYDAk
BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMDgGCCsGAQUFBzAC
hixodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vVEVSRU5BU1NMQ0EzLmNydDAM
BgNVHRMBAf8EAjAAMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdgCkuQmQtBhY
FIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWFmbO6YAAAEAwBHMEUCIQCHBAlo
m8h7zxNCJC1e1Zr/XanBrdDD4xVJb1ktCqhR1wIgJNH4hXG1bIRcbdtBPnt5NbNI
BDUd+Tx1yLSqffyn9NwAdgCHdb/nWXz4jEOZX73zbv9WjUdWNv9KtWDBtOr/XqCD
DwAAAWFmbO9KAAAEAwBHMEUCIDygGOBdd6LaZyQOfG1aHwfaOyTFdIz2X4ecAx3a
fLVqAiEAhglVC2k/Aoe8Z5w4BFkLrUsS9XHUhEHGy2OefVbIb/IAdQC72d+8H4px
tZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWFmbO9tAAAEAwBGMEQCIBkXJ+13
fDlu8wXzHqKSSWXAI5pQjHj/0q3Yn6IMlXG5AiAYkSzgsQy2tGaViEu2pyYbzFYx
ALgYYxtnr2vfvy0d2DANBgkqhkiG9w0BAQsFAAOCAQEAq2gIpIJvlkgT/DzsED+f
+ewJpuEs8zKGOJZ3kUcXQ8rKyY++ldebqgjwgcyXgSz0r4JkgPCAHAAUnyVYEzNm
KcpTG6uBR4fjYg850R6vmYsgDtApgnqkAs6ofDQzqJyQtMqZg68VBKAKjFyoX4Dd
cX44l8dAhZER1QAn+pKSMc90Pc7FFg0q5kitXCa6gAV/qN8xNafGPgOGN8s3cq9E
1zuBQUm3jNHMaoKOIlpc+eRvjKjS92a7xC1/QIZ4xMyarLLVTLxU/gle/F2OoE64
G6UnflcH9l0Q/frKT7moDj2MkujOTbsulwaqt7cmozIjbcNSb0YP+q35S//cQSd+
mw=='''

unipdtestcert = '''MIIGyjCCBbKgAwIBAgIQDtM81U7ImQFNo+O3YUXxUDANBgkqhkiG9w0BAQsFADBk
MQswCQYDVQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJ
QW1zdGVyZGFtMQ8wDQYDVQQKEwZURVJFTkExGDAWBgNVBAMTD1RFUkVOQSBTU0wg
Q0EgMzAeFw0xODAyMjMwMDAwMDBaFw0yMDAyMjgxMjAwMDBaMIGAMQswCQYDVQQG
EwJJVDEPMA0GA1UEBxMGUGFkb3ZhMSowKAYDVQQKDCFVbml2ZXJzaXTDoCBkZWds
aSBTdHVkaSBkaSBQYWRvdmExDDAKBgNVBAsTA0lDVDEmMCQGA1UEAxMdY2xvdWR2
ZW5ldG8tdGVzdC5pY3QudW5pcGQuaXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQD5P/PGFW4wGxq+7z3zkZV8zLYpmndT2fsXowwuOyyxG385fovhyAqX
fpkkfrynxy5j86+6M5Kn6Yb11CJ5bNK7oEjWoz1a7Uct76ksGQiVFWqKwkb6+Na4
k97RgDUs9tAwt1errwptPkb3ivrHYU4xx3XmsH/FOKUaunhiQsa0YGNON0x+H6nA
M/8lL7LZvNoe2SfzShzgOY4b8Y0Pb/S5VYB3kTTQ1LBpTBkGa4GzGTz2Nrbaptb2
RyySZjvEQ4LmNYFGqc94j/flcOYcLx1vbANSuxBylr/0ibDUM30IByoBvEmMN9ls
qSIJukYBaTv0PxGyxSVLAHpL3jveeUBvAgMBAAGjggNZMIIDVTAfBgNVHSMEGDAW
gBRn/YggFCeYxwnSJRm76VERY3VQYjAdBgNVHQ4EFgQUSIwXXlMLnxhywzY/gaVM
TsjIFA0wKAYDVR0RBCEwH4IdY2xvdWR2ZW5ldG8tdGVzdC5pY3QudW5pcGQuaXQw
DgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBr
BgNVHR8EZDBiMC+gLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vVEVSRU5B
U1NMQ0EzLmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL1RFUkVO
QVNTTENBMy5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcC
ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwbgYIKwYB
BQUHAQEEYjBgMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20w
OAYIKwYBBQUHMAKGLGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9URVJFTkFT
U0xDQTMuY3J0MAwGA1UdEwEB/wQCMAAwggF/BgorBgEEAdZ5AgQCBIIBbwSCAWsB
aQB2AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABYcKYW2wAAAQD
AEcwRQIgQUDHXCRxpcJXm6ShwGTqxOtwjxMQ/2aamjPticvCKUgCIQDA/vzimB1v
nsj595nCv4pwvYOBcVK86w1DbGSbPbKViAB2AId1v+dZfPiMQ5lfvfNu/1aNR1Y2
/0q1YMG06v9eoIMPAAABYcKYW+wAAAQDAEcwRQIgK0VPCx4UoaIQZARvCWoNdsZ2
NAMqHr9sZLiNXR/7XLICIQDgAQfBtJrqgRHWE3moqgLSrxnD4rWNDUx6l+7La7k+
agB3ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABYcKYW5EAAAQD
AEgwRgIhAKFuXTsFJWRtoSxVhFlP7ubd4mDXFX+hpnvZWVx0XCQyAiEAgG8lcKoT
1bRNLLBdH3MoYjO2vubuHE1bIPIugnQnyZowDQYJKoZIhvcNAQELBQADggEBAF9N
yF+O3pZylglu3D7GG66RMBHjn3+r29T8f8mf+dEojbqFotx8lmNOjVmfbzG3L5os
bMyMuDyh8u2N/PkTCIYhWpwDqTvigC1Hauu+LnSJjlsAQNAEFPasvU9C0KQtV1Yu
G40dh6I1CbgiOokw7R/ihIq7Wm+WZ7fuDgj5RsUyLeZSjsQOBADuGjHMVmVM8+YL
lNQQD6flGn0HwPh4K8/Sq5LvrsEeQkVQB1rURuGvKOof3mgC97OBooCrRok1sk0P
H1kazFKL0CwoG8/QkHbZxtJ9QIEn5HtFmbCgaGUgHleQH6JgOhLQ2/zUlN63THeN
lFiXhNE58dGWUInQemE='''

md_template = '''
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
                     ID="_a4e3e8671ad845954f451d6a8193c18cd01911f1"
                     entityID="%(entityid)s">

  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <ds:Reference URI="#_a4e3e8671ad845954f451d6a8193c18cd01911f1">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <ds:DigestValue/>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue/>
    <ds:KeyInfo>
      <ds:X509Data />
    </ds:KeyInfo>
  </ds:Signature>

  <md:Extensions xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport">
    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"/>
    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384"/>
    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
    <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha224"/>
    <alg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2009/xmldsig11#dsa-sha256"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
    <alg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
  </md:Extensions>

  <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:1.0:protocol">
    
    <md:Extensions>
      <mdui:UIInfo xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui">
        <mdui:DisplayName xml:lang="en">%(srvtitle)s</mdui:DisplayName>
        <mdui:Description xml:lang="en">%(srvdescr)s</mdui:Description>
        <mdui:InformationURL xml:lang="en">%(srvinfo)s</mdui:InformationURL>
        <mdui:PrivacyStatementURL xml:lang="en">%(srvprivurl)s</mdui:PrivacyStatementURL>
      </mdui:UIInfo>
      <init:RequestInitiator xmlns:init="urn:oasis:names:tc:SAML:profiles:SSO:request-init"
                             Binding="urn:oasis:names:tc:SAML:profiles:SSO:request-init"
                             Location="https://%(srvname)s/Shibboleth.sso/Login"/>
    </md:Extensions>

    <md:KeyDescriptor>
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:KeyName>%(srvname)s</ds:KeyName>
        <ds:X509Data>
          <ds:X509SubjectName>%(srvdn)s</ds:X509SubjectName>
          <ds:X509Certificate>%(srvcert)s</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes192-gcm"/>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc"/>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#rsa-oaep"/>
      <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
    </md:KeyDescriptor>

    <md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://%(srvname)s/Shibboleth.sso/Artifact/SOAP" index="1"/>
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://%(srvname)s/Shibboleth.sso/SLO/SOAP"/>
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://%(srvname)s/Shibboleth.sso/SLO/Redirect"/>
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://%(srvname)s/Shibboleth.sso/SLO/POST"/>
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://%(srvname)s/Shibboleth.sso/SLO/Artifact"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://%(srvname)s/Shibboleth.sso/SAML2/POST" index="1"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://%(srvname)s/Shibboleth.sso/SAML2/POST-SimpleSign" index="2"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://%(srvname)s/Shibboleth.sso/SAML2/Artifact" index="3"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Location="https://%(srvname)s/Shibboleth.sso/SAML2/ECP" index="4"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://%(srvname)s/Shibboleth.sso/SAML/POST" index="5"/>
    <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://%(srvname)s/Shibboleth.sso/SAML/Artifact" index="6"/>
    <md:AttributeConsumingService index="1">
      <md:ServiceName xml:lang="en">%(entityid)s</md:ServiceName>
      <md:RequestedAttribute FriendlyName="eduPersonPrincipalName" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
      <md:RequestedAttribute FriendlyName="mail" Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
      <md:RequestedAttribute FriendlyName="givenName" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" isRequired="true"/>
      <md:RequestedAttribute FriendlyName="sn" Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified" isRequired="true"/>
    </md:AttributeConsumingService>
  </md:SPSSODescriptor>

  <md:Organization>
    <md:OrganizationName xml:lang="en">%(orgname)s</md:OrganizationName>
    <md:OrganizationDisplayName xml:lang="en">%(orgdescr)s</md:OrganizationDisplayName>
    <md:OrganizationURL xml:lang="en">%(orgurl)s</md:OrganizationURL>
  </md:Organization>

  <md:ContactPerson contactType="technical">
    <md:EmailAddress>%(contact)s</md:EmailAddress>
  </md:ContactPerson>
  
</md:EntityDescriptor>
'''

cloud_areapd_params = {
    "entityid" : "https://cloud-areapd.pd.infn.it/dashboard-shib",
    "srvname" : "cloud-areapd.pd.infn.it",
    "srvdn" : "CN=cloud-areapd.pd.infn.it,OU=pd,O=Istituto Nazionale di Fisica Nucleare,L=Frascati,C=IT",
    "srvcert" : infncert,
    "srvtitle" : "Cloud Area Padovana",
    "srvdescr" : "Cloud computing and storage service for researchers of INFN Padova and LNL laboratory, and their international collaborators",
    "srvinfo" : "http://wiki.infn.it/progetti/cloud-areapd/home",
    "srvprivurl" : "http://wiki.infn.it/progetti/cloud-areapd/home",
    "orgname" : "INFN-UniPD",
    "orgdescr" : "Cloud Veneto",
    "orgurl" : "http://wiki.infn.it/progetti/cloud-areapd/home",
    "contact" : "support@cloudveneto.it"
}

cloud_areapd_test_params = {
    "entityid" : "https://cloud-areapd-test.pd.infn.it/dashboard-shib",
    "srvname" : "cloud-areapd-test.pd.infn.it",
    "srvdn" : "CN=cloud-areapd-test.pd.infn.it,OU=pd,O=Istituto Nazionale di Fisica Nucleare,L=Frascati,C=IT",
    "srvcert" : infntestcert,
    "srvtitle" : "Cloud Area Padovana",
    "srvdescr" : "Cloud computing and storage service for researchers of INFN Padova and LNL laboratory, and their international collaborators",
    "srvinfo" : "http://wiki.infn.it/progetti/cloud-areapd/home",
    "srvprivurl" : "http://wiki.infn.it/progetti/cloud-areapd/home",
    "orgname" : "INFN-UniPD",
    "orgdescr" : "Cloud Veneto",
    "orgurl" : "http://wiki.infn.it/progetti/cloud-areapd/home",
    "contact" : "support@cloudveneto.it"
}

cloudveneto_params = {
    "entityid" : "https://cloudveneto.ict.unipd.it/dashboard-shib",
    "srvname" : "cloudveneto.ict.unipd.it",
    "srvdn" : "CN=cloudveneto.ict.unipd.it,OU=ICT,O=Universit\C3\A0 degli Studi di Padova,L=Padova,C=IT",
    "srvcert" : unipdcert,
    "srvtitle" : "Cloud Veneto",
    "srvdescr" : "Cloud computing and storage service for researchers of INFN Padova and University of Padova, and their international collaborators",
    "srvinfo" : "https://cloudveneto.ict.unipd.it/User_Guide/index.html",
    "srvprivurl" : "https://cloudveneto.ict.unipd.it/User_Guide/index.html",
    "orgname" : "INFN-UniPD",
    "orgdescr" : "Cloud Veneto",
    "orgurl" : "https://cloudveneto.ict.unipd.it/User_Guide/index.html",
    "contact" : "support@cloudveneto.it"
}

cloudveneto_test_params = {
    "entityid" : "https://cloudveneto-test.ict.unipd.it/dashboard-shib",
    "srvname" : "cloudveneto-test.ict.unipd.it",
    "srvdn" : "CN=cloudveneto-test.ict.unipd.it,OU=ICT,O=Universit\C3\A0 degli Studi di Padova,L=Padova,C=IT",
    "srvcert" : unipdtestcert,
    "srvtitle" : "Cloud Veneto",
    "srvdescr" : "Cloud computing and storage service for researchers of INFN Padova and University of Padova, and their international collaborators",
    "srvinfo" : "https://cloudveneto-test.ict.unipd.it/User_Guide/index.html",
    "srvprivurl" : "https://cloudveneto-test.ict.unipd.it/User_Guide/index.html",
    "orgname" : "INFN-UniPD",
    "orgdescr" : "Cloud Veneto",
    "orgurl" : "https://cloudveneto-test.ict.unipd.it/User_Guide/index.html",
    "contact" : "support@cloudveneto.it"
}


cmdline = 'xmlsec1 --sign --privkey-pem %(keypem)s,%(certpem)s --trusted-pem %(bundle)s --id-attr:ID urn:oasis:names:tc:SAML:2.0:metadata:EntityDescriptor --output %(outfile)s %(tplfile)s'


def printhelp():
    helptxt = '''Usage: generate-metadata [options]
Options:
--site : one of infn, infntest, unipd, unipdtest
--keyfile : private key pem file
--outfile : location of signed metadata
--tempdir : temporary directory, default /tmp/cap-metadata
'''
    print helptxt
    sys.exit(0)


def main():

    try:
        optTags = [
            "help",
            "site=",
            "keyfile=",
            "tempdir=",
            "outfile="
        ]
        opts, args = getopt.getopt(sys.argv[1:], "", optTags)
    except getopt.GetoptError:
        print "Wrong parameters"
        sys.exit(1)

    opt_table = dict(opts)
    
    if '--help' in opt_table:
        printhelp()
    
    workdir = opt_table.get('--tempdir', os.environ.get("TMPDIR", "/tmp/cap-metadata"))
    if os.path.exists(workdir):
        if os.path.isdir(workdir):
            subprocess.call("rm -rf %s" % workdir, shell=True)
        else:
            print "Wrong temporary directory %s" % workdir
    os.makedirs(workdir)
    
    for topt in ['--site', '--keyfile', '--outfile' ]:
        if not topt in opt_table:
            print "Missing option %s" % topt
            sys.exit(1)

    site = opt_table['--site']
    outfile = opt_table['--outfile']
    
    bundlefname = os.path.join(workdir, 'cabundle.pem')
    tplfname = os.path.join(workdir, 'metadata.xml')
    certfname = os.path.join(workdir, 'cert.pem')
    
    with open(bundlefname, 'w') as bundlefile:
        bundlefile.write(cabundle_pem)

    if site == 'infn':
        with open(tplfname, 'w') as tplfile:
            tplfile.write(md_template % cloud_areapd_params)
        with open(certfname, 'w') as certfile:
            certfile.write("-----BEGIN CERTIFICATE-----\n")
            certfile.write(infncert)
            certfile.write("\n-----END CERTIFICATE-----\n")
    elif site == 'infntest':
        with open(tplfname, 'w') as tplfile:
            tplfile.write(md_template % cloud_areapd_test_params)
        with open(certfname, 'w') as certfile:
            certfile.write("-----BEGIN CERTIFICATE-----\n")
            certfile.write(infntestcert)
            certfile.write("\n-----END CERTIFICATE-----\n")
    elif site == 'unipd':
        with open(tplfname, 'w') as tplfile:
            tplfile.write(md_template % cloudveneto_params)
        with open(certfname, 'w') as certfile:
            certfile.write("-----BEGIN CERTIFICATE-----\n")
            certfile.write(unipdcert)
            certfile.write("\n-----END CERTIFICATE-----\n")
    elif site == 'unipdtest':
        with open(tplfname, 'w') as tplfile:
            tplfile.write(md_template % cloudveneto_test_params)
        with open(certfname, 'w') as certfile:
            certfile.write("-----BEGIN CERTIFICATE-----\n")
            certfile.write(unipdtestcert)
            certfile.write("\n-----END CERTIFICATE-----\n")
    else:
        print "Wrong site %s" % site
        sys.exit(1)

    cmdparams = {
        'keypem' : opt_table['--keyfile'],
        'certpem' : certfname,
        'bundle' : bundlefname,
        'outfile' : opt_table['--outfile'],
        'tplfile' : tplfname
    }
    subprocess.call(cmdline % cmdparams, shell=True)
    subprocess.call("rm -rf %s" % workdir, shell=True)

if __name__ == "__main__":
    main()

