aboutsummaryrefslogtreecommitdiff
path: root/rpkid
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid')
-rw-r--r--rpkid/cronjob.py11
-rwxr-xr-xrpkid/irbe-cli.py22
-rw-r--r--rpkid/irbe-setup.py22
-rwxr-xr-xrpkid/irdbd.py17
-rw-r--r--rpkid/left-right-protocol-samples/pdu.003.xml38
-rw-r--r--rpkid/left-right-protocol-samples/pdu.006.xml38
-rw-r--r--rpkid/left-right-protocol-samples/pdu.008.xml38
-rw-r--r--rpkid/left-right-schema.rnc4
-rw-r--r--rpkid/left-right-schema.rng10
-rwxr-xr-xrpkid/rootd.py23
-rw-r--r--rpkid/rpki/gctx.py33
-rw-r--r--rpkid/rpki/https.py48
-rw-r--r--rpkid/rpki/left_right.py24
-rw-r--r--rpkid/rpki/relaxng.py12
-rw-r--r--rpkid/rpki/sql.py2
-rw-r--r--rpkid/rpki/x509.py104
-rwxr-xr-xrpkid/rpkid.py5
-rw-r--r--rpkid/test-pow-cms.py18
-rw-r--r--rpkid/testbed.py136
-rw-r--r--rpkid/testpoke.py4
20 files changed, 360 insertions, 249 deletions
diff --git a/rpkid/cronjob.py b/rpkid/cronjob.py
index a2ec17a1..6c9de8cf 100644
--- a/rpkid/cronjob.py
+++ b/rpkid/cronjob.py
@@ -40,8 +40,13 @@ if argv:
cfg = rpki.config.parser(cfg_file, "cronjob")
-print rpki.https.client(client_key = rpki.x509.RSA(Auto_file = cfg.get("https-key")),
- client_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("https-cert")),
- server_ta = rpki.x509.X509(Auto_file = cfg.get("https-ta")),
+irbe_key = rpki.x509.RSA( Auto_file = cfg.get("irbe-key"))
+irbe_cert = rpki.x509.X509(Auto_files = cfg.get("irbe-cert"))
+bpki_ta = rpki.x509.X509(Auto_files = cfg.get("bpki-ta"))
+rpkid_cert = rpki.x509.X509(Auto_files = cfg.get("rpkid-cert"))
+
+print rpki.https.client(client_key = irbe_key,
+ client_cert = irbe_cert,
+ server_ta = (bpki_ta, rpkid_cert),
url = cfg.get("https-url"),
msg = "Please run cron now.")
diff --git a/rpkid/irbe-cli.py b/rpkid/irbe-cli.py
index 1e1642e9..c04b8eac 100755
--- a/rpkid/irbe-cli.py
+++ b/rpkid/irbe-cli.py
@@ -156,13 +156,11 @@ if not argv:
cfg = rpki.config.parser(cfg_file, "irbe-cli")
-cms_key = rpki.x509.RSA( Auto_file = cfg.get( "cms-key"))
-cms_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("cms-cert"))
-cms_ta = rpki.x509.X509( Auto_file = cfg.get( "cms-ta"))
-https_key = rpki.x509.RSA( Auto_file = cfg.get( "https-key"))
-https_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("https-cert"))
-https_ta = rpki.x509.X509( Auto_file = cfg.get( "https-ta"))
-https_url = cfg.get( "https-url")
+bpki_ta = rpki.x509.X509(Auto_file = cfg.get("bpki-ta"))
+rpkid_cert = rpki.x509.X509(Auto_files = cfg.get("rpkid-cert"))
+irbe_cert = rpki.x509.X509(Auto_files = cfg.get("irbe-cert"))
+irbe_key = rpki.x509.RSA( Auto_file = cfg.get("irbe-key"))
+https_url = cfg.get("https-url")
q_msg = rpki.left_right.msg()
@@ -174,15 +172,15 @@ while argv:
argv = q_pdu.client_getopt(argv[1:])
q_msg.append(q_pdu)
-q_cms = rpki.left_right.cms_msg.wrap(q_msg, cms_key, cms_certs)
+q_cms = rpki.left_right.cms_msg.wrap(q_msg, irbe_key, irbe_cert)
-der = rpki.https.client(client_key = https_key,
- client_certs = https_certs,
- server_ta = https_ta,
+der = rpki.https.client(client_key = irbe_key,
+ client_cert = irbe_cert,
+ server_ta = (bpki_ta, rpkid_cert),
url = https_url,
msg = q_cms)
-r_msg, r_xml = cms_msg.unwrap(der, r_cms, cms_ta, pretty_print = True)
+r_msg, r_xml = cms_msg.unwrap(der, r_cms, (bpki_ta, rpkid_cert), pretty_print = True)
print r_xml
diff --git a/rpkid/irbe-setup.py b/rpkid/irbe-setup.py
index bbfb8460..e32d6663 100644
--- a/rpkid/irbe-setup.py
+++ b/rpkid/irbe-setup.py
@@ -32,13 +32,11 @@ db = MySQLdb.connect(user = cfg.get("sql-username", section = "irdbd"),
passwd = cfg.get("sql-password", section = "irdbd"))
cur = db.cursor()
-cms_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("cms-cert"))
-cms_key = rpki.x509.RSA( Auto_file = cfg.get( "cms-key"))
-cms_ta = rpki.x509.X509( Auto_file = cfg.get( "cms-ta"))
-https_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("https-cert"))
-https_key = rpki.x509.RSA( Auto_file = cfg.get( "https-key"))
-https_ta = rpki.x509.X509( Auto_file = cfg.get( "https-ta"))
-https_url = cfg.get( "https-url")
+bpki_ta = rpki.x509.X509(Auto_file = cfg.get("bpki-ta"))
+rpkid_cert = rpki.x509.X509(Auto_files = cfg.get("rpkid-cert"))
+irbe_cert = rpki.x509.X509(Auto_files = cfg.get("irbe-cert"))
+irbe_key = rpki.x509.RSA( Auto_file = cfg.get("irbe-key"))
+https_url = cfg.get("https-url")
def call_rpkid(pdu):
"""Hand a PDU to rpkid and get back the response. Just throw an
@@ -47,13 +45,13 @@ def call_rpkid(pdu):
pdu.type = "query"
msg = rpki.left_right.msg((pdu,))
- cms = rpki.x509.left_right_pdu.wrap(msg, cms_key, cms_certs)
- der = rpki.https.client(client_key = https_key,
- client_certs = https_certs,
- server_ta = https_ta,
+ cms = rpki.x509.left_right_pdu.wrap(msg, irbe_key, irbe_cert)
+ der = rpki.https.client(client_key = irbe_key,
+ client_cert = irbe_cert,
+ server_ta = (bpki_ta, rpkid_cert),
url = https_url,
msg = cms)
- msg = rpki.left_right.cms_msg.unwrap(der, cms_ta)
+ msg = rpki.left_right.cms_msg.unwrap(der, (bpki_ta, rpkid_cert))
pdu = msg[0]
assert len(msg) == 1 and pdu.type == "reply" and not isinstance(pdu, rpki.left_right.report_error_elt)
return pdu
diff --git a/rpkid/irdbd.py b/rpkid/irdbd.py
index 49f6079b..cc4eca05 100755
--- a/rpkid/irdbd.py
+++ b/rpkid/irdbd.py
@@ -30,7 +30,7 @@ import rpki.exceptions, rpki.left_right, rpki.log, rpki.x509
def handler(query, path):
try:
- q_msg = rpki.left_right.cms_msg.unwrap(query, cms_ta)
+ q_msg = rpki.left_right.cms_msg.unwrap(query, (bpki_ta, rpkid_cert))
if not isinstance(q_msg, rpki.left_right.msg):
raise rpki.exceptions.BadQuery, "Unexpected %s PDU" % repr(q_msg)
@@ -70,7 +70,7 @@ def handler(query, path):
r_msg.append(r_pdu)
- return 200, rpki.left_right.cms_msg.wrap(r_msg, cms_key, cms_certs)
+ return 200, rpki.left_right.cms_msg.wrap(r_msg, irdbd_key, irdbd_cert)
except Exception, data:
rpki.log.error(traceback.format_exc())
@@ -109,9 +109,10 @@ db = MySQLdb.connect(user = cfg.get("sql-username"),
cur = db.cursor()
-cms_ta = rpki.x509.X509(Auto_file = cfg.get("cms-ta"))
-cms_key = rpki.x509.RSA(Auto_file = cfg.get("cms-key"))
-cms_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("cms-cert"))
+bpki_ta = rpki.x509.X509(Auto_file = cfg.get("bpki-ta"))
+rpkid_cert = rpki.x509.X509(Auto_file = cfg.get("rpkid-cert"))
+irdbd_cert = rpki.x509.X509(Auto_file = cfg.get("irdbd-cert"))
+irdbd_key = rpki.x509.RSA( Auto_file = cfg.get("irdbd-key"))
u = urlparse.urlparse(cfg.get("https-url"))
@@ -122,9 +123,9 @@ assert u.scheme in ("", "https") and \
u.query == "" and \
u.fragment == ""
-rpki.https.server(server_key = rpki.x509.RSA(Auto_file = cfg.get("https-key")),
- server_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("https-cert")),
- client_ta = rpki.x509.X509(Auto_file = cfg.get("https-ta")),
+rpki.https.server(server_key = irdbd_key,
+ server_cert = irdbd_cert,
+ client_ta = (bpki_ta, rpkid_cert),
host = u.hostname or "localhost",
port = u.port or 443,
handlers = ((u.path, handler),))
diff --git a/rpkid/left-right-protocol-samples/pdu.003.xml b/rpkid/left-right-protocol-samples/pdu.003.xml
index e9cf0d06..efca2484 100644
--- a/rpkid/left-right-protocol-samples/pdu.003.xml
+++ b/rpkid/left-right-protocol-samples/pdu.003.xml
@@ -3,5 +3,43 @@
<msg xmlns="http://www.hactrn.net/uris/rpki/left-right-spec/" version="1">
<self action="set" type="query" self_id="42" rekey="yes" reissue="yes" revoke="yes" run_now="yes" publish_world_now="yes" clear_extension_preferences="yes" crl_interval="3600" regen_margin="86400" use_hsm="no">
<extension_preference name="color">Blue</extension_preference>
+ <biz_cert>
+ MIIDGzCCAgOgAwIBAgIJAKi+/+wUhQlxMA0GCSqGSIb3DQEBBQUAMCQxIjAgBgNV
+ BAMTGVRlc3QgQ2VydGlmaWNhdGUgQm9iIFJvb3QwHhcNMDcwODAxMTk1MzEwWhcN
+ MDcwODMxMTk1MzEwWjAkMSIwIAYDVQQDExlUZXN0IENlcnRpZmljYXRlIEJvYiBS
+ b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArKYUtJaM5PH5917S
+ G2ACc7iBYdQO2HYyu8Gb6i9Q2Gxc3cWEX7RTBvgOL79pWf3GIdnoupzMnoZVtY3G
+ Ux2G/0WkmLui2TCeDhcfXdQ4rcp8J3V/6ESj+yuEPPOG8UN17mUKKgujrch6ZvgC
+ DO9AyOK/uXu+ABQXTPsn2pVe2EVh3V004ShLi8GKgVdqb/rW/6GTg0Xb/zLT6WWM
+ uT++6sXTlztJdQYkRamJvKfQDU1naC8mAkGf79Tba0xyBGAUII0GfREY6t4/+NAP
+ 2Yyb3xNlBqcJoTov0JfNKHZcCZePr79j7LK/hkZxxip+Na9xDpE+oQRV+DRukCRJ
+ diqg+wIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTDEsXJe6pjAQD4
+ ULlB7+GMDBlimTAfBgNVHSMEGDAWgBTDEsXJe6pjAQD4ULlB7+GMDBlimTANBgkq
+ hkiG9w0BAQUFAAOCAQEAWWkNcW6S1tKKqtzJsdfhjJiAAPQmOXJskv0ta/8f6Acg
+ cum1YieNdtT0n96P7CUHOWP8QBb91JzeewR7b6WJLwb1Offs3wNq3kk75pJe89r4
+ XY39EZHhMW+Dv0PhIKu2CgD4LeyH1FVTQkF/QObGEmkn+s+HTsuzd1l2VLwcP1Sm
+ sqep6LAlFj62qqaIJzNeQ9NVkBqtkygnYlBOkaBTHfQTux3jYNpEo8JJB5e/WFdH
+ YyMNrG2xMOtIC7T4+IOHgT8PgrNhaeDg9ctewj0X8Qi9nI9nXeinicLX8vj6hdEq
+ 3ORv7RZMJNYqv1HQ3wUE2B7fCPFv7EUwzaCds1kgRQ==
+ </biz_cert>
+ <biz_glue>
+ MIIDGzCCAgOgAwIBAgIJAKi+/+wUhQlxMA0GCSqGSIb3DQEBBQUAMCQxIjAgBgNV
+ BAMTGVRlc3QgQ2VydGlmaWNhdGUgQm9iIFJvb3QwHhcNMDcwODAxMTk1MzEwWhcN
+ MDcwODMxMTk1MzEwWjAkMSIwIAYDVQQDExlUZXN0IENlcnRpZmljYXRlIEJvYiBS
+ b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArKYUtJaM5PH5917S
+ G2ACc7iBYdQO2HYyu8Gb6i9Q2Gxc3cWEX7RTBvgOL79pWf3GIdnoupzMnoZVtY3G
+ Ux2G/0WkmLui2TCeDhcfXdQ4rcp8J3V/6ESj+yuEPPOG8UN17mUKKgujrch6ZvgC
+ DO9AyOK/uXu+ABQXTPsn2pVe2EVh3V004ShLi8GKgVdqb/rW/6GTg0Xb/zLT6WWM
+ uT++6sXTlztJdQYkRamJvKfQDU1naC8mAkGf79Tba0xyBGAUII0GfREY6t4/+NAP
+ 2Yyb3xNlBqcJoTov0JfNKHZcCZePr79j7LK/hkZxxip+Na9xDpE+oQRV+DRukCRJ
+ diqg+wIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTDEsXJe6pjAQD4
+ ULlB7+GMDBlimTAfBgNVHSMEGDAWgBTDEsXJe6pjAQD4ULlB7+GMDBlimTANBgkq
+ hkiG9w0BAQUFAAOCAQEAWWkNcW6S1tKKqtzJsdfhjJiAAPQmOXJskv0ta/8f6Acg
+ cum1YieNdtT0n96P7CUHOWP8QBb91JzeewR7b6WJLwb1Offs3wNq3kk75pJe89r4
+ XY39EZHhMW+Dv0PhIKu2CgD4LeyH1FVTQkF/QObGEmkn+s+HTsuzd1l2VLwcP1Sm
+ sqep6LAlFj62qqaIJzNeQ9NVkBqtkygnYlBOkaBTHfQTux3jYNpEo8JJB5e/WFdH
+ YyMNrG2xMOtIC7T4+IOHgT8PgrNhaeDg9ctewj0X8Qi9nI9nXeinicLX8vj6hdEq
+ 3ORv7RZMJNYqv1HQ3wUE2B7fCPFv7EUwzaCds1kgRQ==
+ </biz_glue>
</self>
</msg>
diff --git a/rpkid/left-right-protocol-samples/pdu.006.xml b/rpkid/left-right-protocol-samples/pdu.006.xml
index 7f51884a..d53fd517 100644
--- a/rpkid/left-right-protocol-samples/pdu.006.xml
+++ b/rpkid/left-right-protocol-samples/pdu.006.xml
@@ -5,5 +5,43 @@
<extension_preference name="name">Launcelot</extension_preference>
<extension_preference name="quest">Holy Grail</extension_preference>
<extension_preference name="color">Blue</extension_preference>
+ <biz_cert>
+ MIIDGzCCAgOgAwIBAgIJAKi+/+wUhQlxMA0GCSqGSIb3DQEBBQUAMCQxIjAgBgNV
+ BAMTGVRlc3QgQ2VydGlmaWNhdGUgQm9iIFJvb3QwHhcNMDcwODAxMTk1MzEwWhcN
+ MDcwODMxMTk1MzEwWjAkMSIwIAYDVQQDExlUZXN0IENlcnRpZmljYXRlIEJvYiBS
+ b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArKYUtJaM5PH5917S
+ G2ACc7iBYdQO2HYyu8Gb6i9Q2Gxc3cWEX7RTBvgOL79pWf3GIdnoupzMnoZVtY3G
+ Ux2G/0WkmLui2TCeDhcfXdQ4rcp8J3V/6ESj+yuEPPOG8UN17mUKKgujrch6ZvgC
+ DO9AyOK/uXu+ABQXTPsn2pVe2EVh3V004ShLi8GKgVdqb/rW/6GTg0Xb/zLT6WWM
+ uT++6sXTlztJdQYkRamJvKfQDU1naC8mAkGf79Tba0xyBGAUII0GfREY6t4/+NAP
+ 2Yyb3xNlBqcJoTov0JfNKHZcCZePr79j7LK/hkZxxip+Na9xDpE+oQRV+DRukCRJ
+ diqg+wIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTDEsXJe6pjAQD4
+ ULlB7+GMDBlimTAfBgNVHSMEGDAWgBTDEsXJe6pjAQD4ULlB7+GMDBlimTANBgkq
+ hkiG9w0BAQUFAAOCAQEAWWkNcW6S1tKKqtzJsdfhjJiAAPQmOXJskv0ta/8f6Acg
+ cum1YieNdtT0n96P7CUHOWP8QBb91JzeewR7b6WJLwb1Offs3wNq3kk75pJe89r4
+ XY39EZHhMW+Dv0PhIKu2CgD4LeyH1FVTQkF/QObGEmkn+s+HTsuzd1l2VLwcP1Sm
+ sqep6LAlFj62qqaIJzNeQ9NVkBqtkygnYlBOkaBTHfQTux3jYNpEo8JJB5e/WFdH
+ YyMNrG2xMOtIC7T4+IOHgT8PgrNhaeDg9ctewj0X8Qi9nI9nXeinicLX8vj6hdEq
+ 3ORv7RZMJNYqv1HQ3wUE2B7fCPFv7EUwzaCds1kgRQ==
+ </biz_cert>
+ <biz_glue>
+ MIIDGzCCAgOgAwIBAgIJAKi+/+wUhQlxMA0GCSqGSIb3DQEBBQUAMCQxIjAgBgNV
+ BAMTGVRlc3QgQ2VydGlmaWNhdGUgQm9iIFJvb3QwHhcNMDcwODAxMTk1MzEwWhcN
+ MDcwODMxMTk1MzEwWjAkMSIwIAYDVQQDExlUZXN0IENlcnRpZmljYXRlIEJvYiBS
+ b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArKYUtJaM5PH5917S
+ G2ACc7iBYdQO2HYyu8Gb6i9Q2Gxc3cWEX7RTBvgOL79pWf3GIdnoupzMnoZVtY3G
+ Ux2G/0WkmLui2TCeDhcfXdQ4rcp8J3V/6ESj+yuEPPOG8UN17mUKKgujrch6ZvgC
+ DO9AyOK/uXu+ABQXTPsn2pVe2EVh3V004ShLi8GKgVdqb/rW/6GTg0Xb/zLT6WWM
+ uT++6sXTlztJdQYkRamJvKfQDU1naC8mAkGf79Tba0xyBGAUII0GfREY6t4/+NAP
+ 2Yyb3xNlBqcJoTov0JfNKHZcCZePr79j7LK/hkZxxip+Na9xDpE+oQRV+DRukCRJ
+ diqg+wIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTDEsXJe6pjAQD4
+ ULlB7+GMDBlimTAfBgNVHSMEGDAWgBTDEsXJe6pjAQD4ULlB7+GMDBlimTANBgkq
+ hkiG9w0BAQUFAAOCAQEAWWkNcW6S1tKKqtzJsdfhjJiAAPQmOXJskv0ta/8f6Acg
+ cum1YieNdtT0n96P7CUHOWP8QBb91JzeewR7b6WJLwb1Offs3wNq3kk75pJe89r4
+ XY39EZHhMW+Dv0PhIKu2CgD4LeyH1FVTQkF/QObGEmkn+s+HTsuzd1l2VLwcP1Sm
+ sqep6LAlFj62qqaIJzNeQ9NVkBqtkygnYlBOkaBTHfQTux3jYNpEo8JJB5e/WFdH
+ YyMNrG2xMOtIC7T4+IOHgT8PgrNhaeDg9ctewj0X8Qi9nI9nXeinicLX8vj6hdEq
+ 3ORv7RZMJNYqv1HQ3wUE2B7fCPFv7EUwzaCds1kgRQ==
+ </biz_glue>
</self>
</msg>
diff --git a/rpkid/left-right-protocol-samples/pdu.008.xml b/rpkid/left-right-protocol-samples/pdu.008.xml
index ce6ded4a..5ae57612 100644
--- a/rpkid/left-right-protocol-samples/pdu.008.xml
+++ b/rpkid/left-right-protocol-samples/pdu.008.xml
@@ -5,6 +5,44 @@
<extension_preference name="name">Launcelot</extension_preference>
<extension_preference name="quest">Holy Grail</extension_preference>
<extension_preference name="color">Blue</extension_preference>
+ <biz_cert>
+ MIIDGzCCAgOgAwIBAgIJAKi+/+wUhQlxMA0GCSqGSIb3DQEBBQUAMCQxIjAgBgNV
+ BAMTGVRlc3QgQ2VydGlmaWNhdGUgQm9iIFJvb3QwHhcNMDcwODAxMTk1MzEwWhcN
+ MDcwODMxMTk1MzEwWjAkMSIwIAYDVQQDExlUZXN0IENlcnRpZmljYXRlIEJvYiBS
+ b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArKYUtJaM5PH5917S
+ G2ACc7iBYdQO2HYyu8Gb6i9Q2Gxc3cWEX7RTBvgOL79pWf3GIdnoupzMnoZVtY3G
+ Ux2G/0WkmLui2TCeDhcfXdQ4rcp8J3V/6ESj+yuEPPOG8UN17mUKKgujrch6ZvgC
+ DO9AyOK/uXu+ABQXTPsn2pVe2EVh3V004ShLi8GKgVdqb/rW/6GTg0Xb/zLT6WWM
+ uT++6sXTlztJdQYkRamJvKfQDU1naC8mAkGf79Tba0xyBGAUII0GfREY6t4/+NAP
+ 2Yyb3xNlBqcJoTov0JfNKHZcCZePr79j7LK/hkZxxip+Na9xDpE+oQRV+DRukCRJ
+ diqg+wIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTDEsXJe6pjAQD4
+ ULlB7+GMDBlimTAfBgNVHSMEGDAWgBTDEsXJe6pjAQD4ULlB7+GMDBlimTANBgkq
+ hkiG9w0BAQUFAAOCAQEAWWkNcW6S1tKKqtzJsdfhjJiAAPQmOXJskv0ta/8f6Acg
+ cum1YieNdtT0n96P7CUHOWP8QBb91JzeewR7b6WJLwb1Offs3wNq3kk75pJe89r4
+ XY39EZHhMW+Dv0PhIKu2CgD4LeyH1FVTQkF/QObGEmkn+s+HTsuzd1l2VLwcP1Sm
+ sqep6LAlFj62qqaIJzNeQ9NVkBqtkygnYlBOkaBTHfQTux3jYNpEo8JJB5e/WFdH
+ YyMNrG2xMOtIC7T4+IOHgT8PgrNhaeDg9ctewj0X8Qi9nI9nXeinicLX8vj6hdEq
+ 3ORv7RZMJNYqv1HQ3wUE2B7fCPFv7EUwzaCds1kgRQ==
+ </biz_cert>
+ <biz_glue>
+ MIIDGzCCAgOgAwIBAgIJAKi+/+wUhQlxMA0GCSqGSIb3DQEBBQUAMCQxIjAgBgNV
+ BAMTGVRlc3QgQ2VydGlmaWNhdGUgQm9iIFJvb3QwHhcNMDcwODAxMTk1MzEwWhcN
+ MDcwODMxMTk1MzEwWjAkMSIwIAYDVQQDExlUZXN0IENlcnRpZmljYXRlIEJvYiBS
+ b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArKYUtJaM5PH5917S
+ G2ACc7iBYdQO2HYyu8Gb6i9Q2Gxc3cWEX7RTBvgOL79pWf3GIdnoupzMnoZVtY3G
+ Ux2G/0WkmLui2TCeDhcfXdQ4rcp8J3V/6ESj+yuEPPOG8UN17mUKKgujrch6ZvgC
+ DO9AyOK/uXu+ABQXTPsn2pVe2EVh3V004ShLi8GKgVdqb/rW/6GTg0Xb/zLT6WWM
+ uT++6sXTlztJdQYkRamJvKfQDU1naC8mAkGf79Tba0xyBGAUII0GfREY6t4/+NAP
+ 2Yyb3xNlBqcJoTov0JfNKHZcCZePr79j7LK/hkZxxip+Na9xDpE+oQRV+DRukCRJ
+ diqg+wIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTDEsXJe6pjAQD4
+ ULlB7+GMDBlimTAfBgNVHSMEGDAWgBTDEsXJe6pjAQD4ULlB7+GMDBlimTANBgkq
+ hkiG9w0BAQUFAAOCAQEAWWkNcW6S1tKKqtzJsdfhjJiAAPQmOXJskv0ta/8f6Acg
+ cum1YieNdtT0n96P7CUHOWP8QBb91JzeewR7b6WJLwb1Offs3wNq3kk75pJe89r4
+ XY39EZHhMW+Dv0PhIKu2CgD4LeyH1FVTQkF/QObGEmkn+s+HTsuzd1l2VLwcP1Sm
+ sqep6LAlFj62qqaIJzNeQ9NVkBqtkygnYlBOkaBTHfQTux3jYNpEo8JJB5e/WFdH
+ YyMNrG2xMOtIC7T4+IOHgT8PgrNhaeDg9ctewj0X8Qi9nI9nXeinicLX8vj6hdEq
+ 3ORv7RZMJNYqv1HQ3wUE2B7fCPFv7EUwzaCds1kgRQ==
+ </biz_glue>
</self>
<self action="list" type="reply" self_id="99">
<extension_preference name="name">Arthur, King of the Britons</extension_preference>
diff --git a/rpkid/left-right-schema.rnc b/rpkid/left-right-schema.rnc
index dc511611..88adb520 100644
--- a/rpkid/left-right-schema.rnc
+++ b/rpkid/left-right-schema.rnc
@@ -57,7 +57,9 @@ self_payload = (attribute use_hsm { "yes" | "no" }?,
element extension_preference {
attribute name { xsd:token { maxLength="1024" } },
xsd:string { maxLength="512000" }
- }*)
+ }*,
+ element biz_cert { base64 }?,
+ element biz_glue { base64 }?)
self_id = attribute self_id { sql_id }
diff --git a/rpkid/left-right-schema.rng b/rpkid/left-right-schema.rng
index 07558aa5..05bb94a5 100644
--- a/rpkid/left-right-schema.rng
+++ b/rpkid/left-right-schema.rng
@@ -221,6 +221,16 @@
</data>
</element>
</zeroOrMore>
+ <optional>
+ <element name="biz_cert">
+ <ref name="base64"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="biz_glue">
+ <ref name="base64"/>
+ </element>
+ </optional>
</define>
<define name="self_id">
<attribute name="self_id">
diff --git a/rpkid/rootd.py b/rpkid/rootd.py
index 6bae0b7d..b60bc4a8 100755
--- a/rpkid/rootd.py
+++ b/rpkid/rootd.py
@@ -132,19 +132,19 @@ class cms_msg(rpki.up_down.cms_msg):
def up_down_handler(query, path):
try:
- q_msg = cms_msg.unwrap(query, cms_ta)
+ q_msg = cms_msg.unwrap(query, (bpki_ta, child_bpki_cert))
except Exception, data:
rpki.log.error(traceback.format_exc())
return 400, "Could not process PDU: %s" % data
try:
r_msg = q_msg.serve_top_level(None)
- r_cms = cms_msg.wrap(r_msg, cms_key, cms_certs)
+ r_cms = cms_msg.wrap(r_msg, rootd_bpki_key, rootd_bpki_cert)
return 200, r_cms
except Exception, data:
rpki.log.error(traceback.format_exc())
try:
r_msg = q_msg.serve_error(data)
- r_cms = cms_msg.wrap(r_msg, cms_key, cms_certs)
+ r_cms = cms_msg.wrap(r_msg, rootd_bpki_key, rootd_bpki_cert)
return 200, r_cms
except Exception, data:
rpki.log.error(traceback.format_exc())
@@ -169,13 +169,10 @@ if argv:
cfg = rpki.config.parser(cfg_file, "rootd")
-cms_ta = rpki.x509.X509(Auto_file = cfg.get("cms-ta"))
-cms_key = rpki.x509.RSA(Auto_file = cfg.get("cms-key"))
-cms_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("cms-cert"))
-
-https_ta = rpki.x509.X509(Auto_file = cfg.get("https-ta"))
-https_key = rpki.x509.RSA(Auto_file = cfg.get("https-key"))
-https_certs = rpki.x509.X509_chain(Auto_files = cfg.multiget("https-cert"))
+bpki_ta = rpki.x509.X509(Auto_file = cfg.get("bpki-ta"))
+rootd_bpki_key = rpki.x509.RSA( Auto_file = cfg.get("rootd-bpki-key"))
+rootd_bpki_cert = rpki.x509.X509(Auto_file = cfg.get("rootd-bpki-cert"))
+child_bpki_cert = rpki.x509.X509(Auto_file = cfg.get("child-bpki-cert"))
https_server_host = cfg.get("server-host", "")
https_server_port = int(cfg.get("server-port"))
@@ -190,9 +187,9 @@ rootd_name = cfg.get("rootd_name", "wombat")
rootd_base = cfg.get("rootd_base", "rsync://" + rootd_name + ".invalid/")
rootd_cert = cfg.get("rootd_cert", rootd_base + "rootd.cer")
-rpki.https.server(server_key = https_key,
- server_certs = https_certs,
- client_ta = https_ta,
+rpki.https.server(server_key = rootd_bpki_key,
+ server_cert = rootd_bpki_cert,
+ client_ta = (bpki_ta, child_bpki_cert),
host = https_server_host,
port = https_server_port,
handlers = up_down_handler)
diff --git a/rpkid/rpki/gctx.py b/rpkid/rpki/gctx.py
index 2bdc5daf..127205f7 100644
--- a/rpkid/rpki/gctx.py
+++ b/rpkid/rpki/gctx.py
@@ -36,10 +36,11 @@ class global_context(object):
passwd = cfg.get("sql-password"))
self.cur = self.db.cursor()
- self.ta_irdb = rpki.x509.X509(Auto_file = cfg.get("ta-irdb"))
- self.ta_irbe = rpki.x509.X509(Auto_file = cfg.get("ta-irbe"))
- self.ee_key = rpki.x509.RSA(Auto_file = cfg.get("ee-key"))
- self.cert_chain = rpki.x509.X509_chain(Auto_files = cfg.multiget("cert-chain"))
+ self.bpki_ta = rpki.x509.X509(Auto_file = cfg.get("bpki-ta"))
+ self.irdb_cert = rpki.x509.X509(Auto_file = cfg.get("irdb-cert"))
+ self.irbe_cert = rpki.x509.X509(Auto_file = cfg.get("irbe-cert"))
+ self.rpkid_cert = rpki.x509.X509(Auto_file = cfg.get("rpkid-cert"))
+ self.rpkid_key = rpki.x509.RSA( Auto_file = cfg.get("rpkid-key"))
self.irdb_url = cfg.get("irdb-url")
@@ -69,14 +70,14 @@ class global_context(object):
q_msg[0].type = "query"
q_msg[0].self_id = self_id
q_msg[0].child_id = child_id
- q_cms = rpki.left_right.cms_msg.wrap(q_msg, self.ee_key, self.cert_chain)
+ q_cms = rpki.left_right.cms_msg.wrap(q_msg, self.rpkid_key, self.rpkid_cert)
der = rpki.https.client(
- client_key = self.ee_key,
- client_certs = self.cert_chain,
- server_ta = self.ta_irdb,
+ client_key = self.rpkid_key,
+ client_cert = self.rpkid_cert,
+ server_ta = self.irdb_cert,
url = self.irdb_url,
msg = q_cms)
- r_msg = rpki.left_right.cms_msg.unwrap(der, self.ta_irdb)
+ r_msg = rpki.left_right.cms_msg.unwrap(der, self.irdb_cert)
if len(r_msg) == 0 or not isinstance(r_msg[0], rpki.left_right.list_resources_elt) or r_msg[0].type != "reply":
raise rpki.exceptions.BadIRDBReply, "Unexpected response to IRDB query: %s" % lxml.etree.tostring(r_msg.toXML(), pretty_print = True, encoding = "us-ascii")
return rpki.resource_set.resource_bag(
@@ -107,9 +108,9 @@ class global_context(object):
"""Process one left-right PDU."""
rpki.log.trace()
try:
- q_msg = rpki.left_right.cms_msg.unwrap(query, self.ta_irbe)
+ q_msg = rpki.left_right.cms_msg.unwrap(query, self.bpki_ta)
r_msg = q_msg.serve_top_level(self)
- reply = rpki.left_right.cms_msg.wrap(r_msg, self.ee_key, self.cert_chain)
+ reply = rpki.left_right.cms_msg.wrap(r_msg, self.rpkid_key, self.rpkid_cert)
self.sql_sweep()
return 200, reply
except Exception, data:
@@ -155,7 +156,7 @@ class global_context(object):
"""Clear cached HTTPS trust anchor X509Store."""
if self.https_ta_cache is not None:
- rpki.log.debug("Clearing HTTPS trust anchor cache")
+ rpki.log.debug("Clearing HTTPS trusted cert cache")
self.https_ta_cache = None
def build_x509store(self):
@@ -168,15 +169,17 @@ class global_context(object):
"""
if self.https_ta_cache is None:
-
store = POW.X509Store()
+ selves = rpki.left_right.self_elt.sql_fetch_all(self)
children = rpki.left_right.child_elt.sql_fetch_all(self)
certs = [c.peer_biz_cert for c in children if c.peer_biz_cert is not None] + \
[c.peer_biz_glue for c in children if c.peer_biz_glue is not None] + \
- [ self.ta_irbe ]
+ [s.biz_cert for s in selves if s.biz_cert is not None] + \
+ [s.biz_glue for s in selves if s.biz_glue is not None] + \
+ [self.irbe_cert, self.irdb_cert, self.bpki_ta]
for x in certs:
if rpki.https.debug_tls_certs:
- rpki.log.debug("HTTPS dynamic trust anchor %s" % x.getSubject())
+ rpki.log.debug("HTTPS dynamic trusted cert %s" % x.getSubject())
store.addTrust(x.get_POW())
self.https_ta_cache = store
diff --git a/rpkid/rpki/https.py b/rpkid/rpki/https.py
index db94e721..b5338f5d 100644
--- a/rpkid/rpki/https.py
+++ b/rpkid/rpki/https.py
@@ -31,10 +31,17 @@ import POW
disable_tls_certificate_validation_exceptions = False
# Chatter suppression
-debug_tls_certs = False
+debug_tls_certs = True
rpki_content_type = "application/x-rpki"
+def tlslite_certChain(x509):
+ """Utility function to construct tlslite certChains."""
+ if isinstance(x509, rpki.x509.X509):
+ return tlslite.api.X509CertChain([x509.get_tlslite()])
+ else:
+ return tlslite.api.X509CertChain([x.get_tlslite() for x in x509])
+
class Checker(tlslite.api.Checker):
"""Derived class to handle X.509 client certificate checking."""
@@ -43,13 +50,18 @@ class Checker(tlslite.api.Checker):
self.dynamic_x509store = dynamic_x509store
- if dynamic_x509store is None:
- self.x509store = POW.X509Store()
+ if dynamic_x509store is not None:
+ return
+
+ self.x509store = POW.X509Store()
+
+ if isinstance(trust_anchor, rpki.x509.X509):
+ trust_anchor = (trust_anchor,)
+
+ for x in trust_anchor:
if debug_tls_certs:
- rpki.log.debug("HTTPS trust anchor %s" % trust_anchor.getSubject())
- self.x509store.addTrust(trust_anchor.get_POW())
- elif debug_tls_certs:
- rpki.log.debug("HTTPS dynamic trust anchors")
+ rpki.log.debug("HTTPS trusted cert %s" % x.getSubject())
+ self.x509store.addTrust(x.get_POW())
def x509store_thunk(self):
if self.dynamic_x509store is not None:
@@ -83,17 +95,17 @@ class httpsClient(tlslite.api.HTTPTLSConnection):
"""Derived class to let us replace the default Checker."""
def __init__(self, host, port = None,
- client_certs = None, client_key = None,
+ client_cert = None, client_key = None,
server_ta = None, settings = None):
"""Create a new httpsClient."""
tlslite.api.HTTPTLSConnection.__init__(
self, host = host, port = port, settings = settings,
- certChain = client_certs, privateKey = client_key)
+ certChain = client_cert, privateKey = client_key)
self.checker = Checker(trust_anchor = server_ta)
-def client(msg, client_key, client_certs, server_ta, url, timeout = 300):
+def client(msg, client_key, client_cert, server_ta, url, timeout = 300):
"""Open client HTTPS connection, send a message, wait for response.
This function wraps most of what one needs to do to send a message
@@ -112,8 +124,8 @@ def client(msg, client_key, client_certs, server_ta, url, timeout = 300):
u.fragment == ""
if debug_tls_certs:
- for client_cert in client_certs:
- rpki.log.debug("Sending client TLS cert %s" % client_cert.getSubject())
+ for cert in (client_cert,) if isinstance(client_cert, rpki.x509.X509) else client_cert:
+ rpki.log.debug("Sending client TLS cert %s" % cert.getSubject())
# We could add a "settings = foo" argument to the following call to
# pass in a tlslite.HandshakeSettings object that would let us
@@ -122,7 +134,7 @@ def client(msg, client_key, client_certs, server_ta, url, timeout = 300):
httpc = httpsClient(host = u.hostname or "localhost",
port = u.port or 443,
client_key = client_key.get_tlslite(),
- client_certs = client_certs.tlslite_certChain(),
+ client_cert = tlslite_certChain(client_cert),
server_ta = server_ta)
httpc.connect()
httpc.sock.settimeout(timeout)
@@ -179,12 +191,12 @@ class httpsServer(tlslite.api.TLSSocketServerMixIn, BaseHTTPServer.HTTPServer):
rpki_sessionCache = None
rpki_server_key = None
- rpki_server_certs = None
+ rpki_server_cert = None
rpki_checker = None
def handshake(self, tlsConnection):
"""TLS handshake handler."""
- assert self.rpki_server_certs is not None
+ assert self.rpki_server_cert is not None
assert self.rpki_server_key is not None
assert self.rpki_sessionCache is not None
@@ -194,7 +206,7 @@ class httpsServer(tlslite.api.TLSSocketServerMixIn, BaseHTTPServer.HTTPServer):
# to pass in a tlslite.HandshakeSettings object that would let
# us insist on, eg, particular SSL/TLS versions.
#
- tlsConnection.handshakeServer(certChain = self.rpki_server_certs,
+ tlsConnection.handshakeServer(certChain = self.rpki_server_cert,
privateKey = self.rpki_server_key,
sessionCache = self.rpki_sessionCache,
checker = self.rpki_checker,
@@ -205,7 +217,7 @@ class httpsServer(tlslite.api.TLSSocketServerMixIn, BaseHTTPServer.HTTPServer):
rpki.log.warn("TLS handshake failure: " + str(error))
return False
-def server(handlers, server_key, server_certs, port = 4433, host = "", client_ta = None, dynamic_x509store = None):
+def server(handlers, server_key, server_cert, port = 4433, host = "", client_ta = None, dynamic_x509store = None):
"""Run an HTTPS server and wait (forever) for connections."""
if not isinstance(handlers, (tuple, list)):
@@ -217,7 +229,7 @@ def server(handlers, server_key, server_certs, port = 4433, host = "", client_ta
httpd = httpsServer((host, port), boundRequestHandler)
httpd.rpki_server_key = server_key.get_tlslite()
- httpd.rpki_server_certs = server_certs.tlslite_certChain()
+ httpd.rpki_server_cert = tlslite_certChain(server_cert)
httpd.rpki_sessionCache = tlslite.api.SessionCache()
httpd.rpki_checker = Checker(trust_anchor = client_ta, dynamic_x509store = dynamic_x509store)
diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py
index 3361ac5e..db7f9191 100644
--- a/rpkid/rpki/left_right.py
+++ b/rpkid/rpki/left_right.py
@@ -215,15 +215,18 @@ class self_elt(data_elt):
element_name = "self"
attributes = ("action", "type", "tag", "self_id", "crl_interval", "regen_margin")
- elements = ("extension_preference",)
+ elements = ("extension_preference", "biz_cert", "biz_glue")
booleans = ("rekey", "reissue", "revoke", "run_now", "publish_world_now", "clear_extension_preferences")
- sql_template = rpki.sql.template("self", "self_id", "use_hsm", "crl_interval", "regen_margin")
+ sql_template = rpki.sql.template("self", "self_id", "use_hsm", "crl_interval", "regen_margin",
+ ("biz_cert", rpki.x509.X509), ("biz_glue", rpki.x509.X509))
self_id = None
use_hsm = False
crl_interval = None
regen_margin = None
+ biz_cert = None
+ biz_glue = None
def __init__(self):
"""Initialize a self_elt."""
@@ -322,14 +325,19 @@ class self_elt(data_elt):
self.prefs.append(pref)
stack.append(pref)
pref.startElement(stack, name, attrs)
- else:
+ elif name not in ("biz_cert", "biz_glue"):
assert name == "self", "Unexpected name %s, stack %s" % (name, stack)
self.read_attrs(attrs)
def endElement(self, stack, name, text):
"""Handle <self/> element."""
- assert name == "self", "Unexpected name %s, stack %s" % (name, stack)
- stack.pop()
+ if name == "biz_cert":
+ self.biz_cert = rpki.x509.X509(Base64 = text)
+ elif name == "biz_glue":
+ self.biz_glue = rpki.x509.X509(Base64 = text)
+ else:
+ assert name == "self", "Unexpected name %s, stack %s" % (name, stack)
+ stack.pop()
def toXML(self):
"""Generate <self/> element."""
@@ -443,12 +451,12 @@ class bsc_elt(data_elt):
def __init__(self):
"""Initialize bsc_elt."""
- self.signing_cert = rpki.x509.X509_chain()
+ self.signing_cert = []
def sql_fetch_hook(self):
"""Extra SQL fetch actions for bsc_elt -- handle signing certs."""
self.gctx.cur.execute("SELECT cert FROM bsc_cert WHERE bsc_id = %s", (self.bsc_id,))
- self.signing_cert[:] = [rpki.x509.X509(DER = x) for (x,) in self.gctx.cur.fetchall()]
+ self.signing_cert = [rpki.x509.X509(DER = x) for (x,) in self.gctx.cur.fetchall()]
def sql_insert_hook(self):
"""Extra SQL insert actions for bsc_elt -- handle signing certs."""
@@ -613,7 +621,7 @@ class parent_elt(data_elt):
der = rpki.https.client(server_ta = self.peer_biz_cert,
client_key = bsc.private_key_id,
- client_certs = bsc.signing_cert,
+ client_cert = bsc.signing_cert,
msg = q_cms,
url = self.peer_contact_uri)
diff --git a/rpkid/rpki/relaxng.py b/rpkid/rpki/relaxng.py
index c04a3158..8b3ab862 100644
--- a/rpkid/rpki/relaxng.py
+++ b/rpkid/rpki/relaxng.py
@@ -6,7 +6,7 @@ import lxml.etree
## Parsed RelaxNG left_right schema
left_right = lxml.etree.RelaxNG(lxml.etree.fromstring('''<?xml version="1.0" encoding="UTF-8"?>
<!--
- $Id: left-right-schema.rng 1668 2008-04-16 04:58:58Z sra $
+ $Id: left-right-schema.rnc 1668 2008-04-16 04:58:58Z sra $
RelaxNG (Compact Syntax) Schema for RPKI left-right protocol.
@@ -227,6 +227,16 @@ left_right = lxml.etree.RelaxNG(lxml.etree.fromstring('''<?xml version="1.0" enc
</data>
</element>
</zeroOrMore>
+ <optional>
+ <element name="biz_cert">
+ <ref name="base64"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="biz_glue">
+ <ref name="base64"/>
+ </element>
+ </optional>
</define>
<define name="self_id">
<attribute name="self_id">
diff --git a/rpkid/rpki/sql.py b/rpkid/rpki/sql.py
index 892e99b7..85c85a6a 100644
--- a/rpkid/rpki/sql.py
+++ b/rpkid/rpki/sql.py
@@ -675,7 +675,7 @@ class ca_detail_obj(sql_persistant):
nextUpdate = nextUpdate,
names_and_objs = certs,
keypair = self.manifest_private_key_id,
- certs = rpki.x509.X509_chain(self.latest_manifest_cert))
+ certs = self.latest_manifest_cert)
repository.publish(self.latest_manifest, self.manifest_uri(ca))
diff --git a/rpkid/rpki/x509.py b/rpkid/rpki/x509.py
index a74fc429..71ff4d53 100644
--- a/rpkid/rpki/x509.py
+++ b/rpkid/rpki/x509.py
@@ -356,74 +356,6 @@ class X509(DER_object):
return X509(POWpkix = cert)
-class X509_chain(list):
- """Collections of certs.
-
- This class provides sorting and conversion functions for various
- packages.
- """
-
- def __init__(self, *args, **kw):
- """Initialize an X509_chain."""
- if args:
- self[:] = args
- elif "PEM_files" in kw:
- self.load_from_PEM(kw["PEM_files"])
- elif "DER_files" in kw:
- self.load_from_DER(kw["DER_files"])
- elif "Auto_files" in kw:
- self.load_from_Auto(kw["Auto_files"])
- elif kw:
- raise TypeError
-
- def chainsort(self):
- """Sort a bag of certs into a chain, leaf first.
-
- Various other routines want their certs presented in this order.
- """
- if len(self) > 1:
- bag = self[:]
- issuer_names = [x.getIssuer() for x in bag]
- subject_map = dict([(x.getSubject(), x) for x in bag])
- chain = []
- for subject in subject_map:
- if subject not in issuer_names:
- cert = subject_map[subject]
- chain.append(cert)
- bag.remove(cert)
- if len(chain) != 1:
- raise rpki.exceptions.NotACertificateChain, "Certificates in bag don't form a proper chain"
- while bag:
- cert = subject_map[chain[-1].getIssuer()]
- chain.append(cert)
- bag.remove(cert)
- self[:] = chain
-
- def tlslite_certChain(self):
- """Return a certChain in the format tlslite likes."""
- self.chainsort()
- return tlslite.api.X509CertChain([x.get_tlslite() for x in self])
-
- def tlslite_trustList(self):
- """Return a trustList in the format tlslite likes."""
- return [x.get_tlslite() for x in self]
-
- def clear(self):
- """Drop all certs from this bag onto the floor."""
- self[:] = []
-
- def load_from_PEM(self, files):
- """Load a set of certs from a list of PEM files."""
- self.extend([X509(PEM_file=f) for f in files])
-
- def load_from_DER(self, files):
- """Load a set of certs from a list of DER files."""
- self.extend([X509(DER_file=f) for f in files])
-
- def load_from_Auto(self, files):
- """Load a set of certs from a list of DER or PEM files (guessing)."""
- self.extend([X509(Auto_file=f) for f in files])
-
class PKCS10(DER_object):
"""Class to hold a PKCS #10 request."""
@@ -622,6 +554,7 @@ class CMS_object(DER_object):
econtent_oid = POWify("id-data")
dump_on_verify_failure = False
+ debug_cms_certs = True
def get_DER(self):
"""Get the DER value of this CMS_object."""
@@ -644,14 +577,27 @@ class CMS_object(DER_object):
"""Verify CMS wrapper and store inner content."""
cms = POW.derRead(POW.CMS_MESSAGE, self.get_DER())
+
if cms.eContentType() != self.econtent_oid:
raise rpki.exceptions.WrongEContentType, "Got CMS eContentType %s, expected %s" % (cms.eContentType(), self.econtent_oid)
+
store = POW.X509Store()
- if isinstance(ta, (tuple, list)):
- for x in ta:
- store.addTrust(x.get_POW())
- else:
- store.addTrust(ta.get_POW())
+
+ if isinstance(ta, X509):
+ ta = (ta,)
+
+ for x in ta:
+ if self.debug_cms_certs:
+ rpki.log.debug("CMS trusted cert %s" % x.getSubject())
+ store.addTrust(x.get_POW())
+
+ if self.debug_cms_certs:
+ try:
+ for x in cms.certs():
+ rpki.log.debug("Received CMS cert %s" % x.getSubject())
+ except:
+ pass
+
try:
content = cms.verify(store)
except:
@@ -659,17 +605,25 @@ class CMS_object(DER_object):
print "CMS verification failed, dumping ASN.1:"
self.dumpasn1()
raise rpki.exceptions.CMSVerificationFailed, "CMS verification failed"
+
self.decode(content)
return self.get_content()
def sign(self, keypair, certs, crls = None, no_certs = False):
"""Sign and wrap inner content."""
+ if isinstance(certs, X509):
+ cert = certs
+ certs = ()
+ else:
+ cert = certs[0]
+ certs = certs[1:]
+
cms = POW.CMS()
- cms.sign(certs[0].get_POW(),
+ cms.sign(cert.get_POW(),
keypair.get_POW(),
self.encode(),
- [x.get_POW() for x in certs[1:]],
+ [x.get_POW() for x in certs],
crls,
self.econtent_oid,
POW.CMS_NOCERTS if no_certs else 0)
diff --git a/rpkid/rpkid.py b/rpkid/rpkid.py
index 103a24f6..0668a24f 100755
--- a/rpkid/rpkid.py
+++ b/rpkid/rpkid.py
@@ -54,9 +54,8 @@ gctx = rpki.gctx.global_context(cfg)
rpki.https.server(host = gctx.https_server_host,
port = gctx.https_server_port,
- server_key = gctx.ee_key,
- server_certs = gctx.cert_chain,
- client_ta = gctx.ta_irbe,
+ server_key = gctx.rpkid_key,
+ server_cert = gctx.rpkid_cert,
dynamic_x509store = gctx.build_x509store,
handlers = (("/left-right", gctx.left_right_handler),
("/up-down/", gctx.up_down_handler),
diff --git a/rpkid/test-pow-cms.py b/rpkid/test-pow-cms.py
index f4196f73..e65cd189 100644
--- a/rpkid/test-pow-cms.py
+++ b/rpkid/test-pow-cms.py
@@ -14,7 +14,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-import POW, rpki.x509, os
+import POW, rpki.x509, os, traceback
key = rpki.x509.RSA(Auto_file = "biz-certs/Alice-EE.key").get_POW()
ee = rpki.x509.X509(Auto_file = "biz-certs/Alice-EE.cer").get_POW()
@@ -53,7 +53,21 @@ for args in ((ee, key, plaintext, [ca], (), oid),
cms = POW.CMS()
cms.sign(*args)
- if True:
+ print "Certs:"
+ try:
+ for x in cms.certs():
+ print x.pprint()
+ except:
+ pass
+
+ print "CRLs:"
+ try:
+ for c in cms.crls():
+ print c.pprint()
+ except:
+ pass
+
+ if False:
print cms.pprint()
cms.verify(store, [ee])
diff --git a/rpkid/testbed.py b/rpkid/testbed.py
index 043a4219..768f0c6b 100644
--- a/rpkid/testbed.py
+++ b/rpkid/testbed.py
@@ -111,10 +111,6 @@ rcynic_stats = cfg.get("rcynic_stats", "xsltproc --param refresh 0 ../../rcy
rpki_sql_file = cfg.get("rpki_sql_file", "../docs/rpki-db-schema.sql")
irdb_sql_file = cfg.get("irdb_sql_file", "../docs/sample-irdb.sql")
-testbed_key = None
-testbed_certs = None
-rootd_ta = None
-
startup_delay = int(cfg.get("startup_delay", "10"))
def main():
@@ -143,14 +139,8 @@ def main():
rpki.log.info("Reading master YAML configuration")
db = allocation_db(yaml_script.pop(0))
- rpki.log.info("Constructing biz keys and certs for control script")
- setup_biz_cert_chain(testbed_name)
- global testbed_key, testbed_certs
- testbed_key = rpki.x509.RSA(PEM_file = testbed_name + "-EE.key")
- testbed_certs = rpki.x509.X509_chain(PEM_files = (testbed_name + "-EE.cer", testbed_name + "-CA.cer"))
-
rpki.log.info("Constructing biz keys and certs for rootd")
- setup_biz_cert_chain(rootd_name)
+ setup_biz_cert_chain(rootd_name, ee = ("RPKI",))
global rootd_ta
rootd_ta = rpki.x509.X509(PEM_file = rootd_name + "-TA.cer")
@@ -158,7 +148,7 @@ def main():
a.setup_biz_certs()
setup_publication()
- setup_rootd(db.root.name)
+ setup_rootd(db.root.name, "SELF-1")
setup_rsyncd()
setup_rcynic()
@@ -485,9 +475,10 @@ class allocation(object):
def setup_biz_certs(self):
"""Create business certs for this entity."""
rpki.log.info("Constructing biz keys and certs for %s" % self.name)
- for tag in ("RPKI", "IRDB"):
- setup_biz_cert_chain(self.name + "-" + tag)
- self.rpkid_ta = rpki.x509.X509(PEM_file = self.name + "-RPKI-TA.cer")
+ setup_biz_cert_chain(self.name, ee = ("RPKI", "IRDB", "IRBE"), ca = ("SELF-1",))
+ self.rpkid_ta = rpki.x509.X509(PEM_file = self.name + "-TA.cer")
+ self.irbe_cer = rpki.x509.X509(PEM_file = self.name + "-IRBE.cer")
+ self.irbe_key = rpki.x509.RSA( PEM_file = self.name + "-IRBE.key")
def setup_conf_file(self):
"""Write config files for this entity."""
@@ -567,13 +558,13 @@ class allocation(object):
rpki.log.info("Calling rpkid for %s" % self.name)
pdu.type = "query"
msg = rpki.left_right.msg((pdu,))
- cms, xml = rpki.left_right.cms_msg.wrap(msg, testbed_key, testbed_certs, pretty_print = True)
+ cms, xml = rpki.left_right.cms_msg.wrap(msg, self.irbe_key, self.irbe_cer, pretty_print = True)
rpki.log.debug(xml)
url = "https://localhost:%d/left-right" % self.rpki_port
rpki.log.debug("Attempting to connect to %s" % url)
der = rpki.https.client(
- client_key = testbed_key,
- client_certs = testbed_certs,
+ client_key = self.irbe_key,
+ client_cert = self.irbe_cer,
server_ta = self.rpkid_ta,
url = url,
msg = cms)
@@ -602,22 +593,26 @@ class allocation(object):
"""
rpki.log.info("Creating rpkid self object for %s" % self.name)
+ self_ca = rpki.x509.X509(Auto_file = self.name + "-SELF-1.cer")
self.self_id = self.call_rpkid(rpki.left_right.self_elt.make_pdu(
- action = "create", crl_interval = self.crl_interval, regen_margin = self.regen_margin)).self_id
+ action = "create", crl_interval = self.crl_interval, regen_margin = self.regen_margin, biz_cert = self_ca)).self_id
rpki.log.info("Creating rpkid BSC object for %s" % self.name)
pdu = self.call_rpkid(rpki.left_right.bsc_elt.make_pdu(action = "create", self_id = self.self_id, generate_keypair = True))
self.bsc_id = pdu.bsc_id
rpki.log.info("Issuing BSC EE cert for %s" % self.name)
- cmd = (prog_openssl, "x509", "-req", "-CA", self.name + "-RPKI-CA.cer", "-CAkey", self.name + "-RPKI-CA.key", "-CAserial", self.name + "-RPKI-CA.srl",
- "-extfile", self.name + "-RPKI-EE.cnf", "-extensions", "req_x509_ext")
+ cmd = (prog_openssl, "x509", "-req", "-extfile", self.name + "-RPKI.cnf", "-extensions", "req_x509_ext", "-days", "30",
+ "-CA", self.name + "-SELF-1.cer", "-CAkey", self.name + "-SELF-1.key", "-CAcreateserial")
signer = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
- bsc_ee = rpki.x509.X509(PEM = signer.communicate(input = pdu.pkcs10_request.get_PEM())[0])
+ signed = signer.communicate(input = pdu.pkcs10_request.get_PEM())
+ if not signed[0]:
+ rpki.log.error(signed[1])
+ raise RuntimeError, "Couldn't issue BSC EE certificate"
+ bsc_ee = rpki.x509.X509(PEM = signed[0])
rpki.log.info("Installing BSC EE cert for %s" % self.name)
- self.call_rpkid(rpki.left_right.bsc_elt.make_pdu(action = "set", self_id = self.self_id, bsc_id = self.bsc_id,
- signing_cert = [bsc_ee, rpki.x509.X509(PEM_file = self.name + "-RPKI-CA.cer")]))
+ self.call_rpkid(rpki.left_right.bsc_elt.make_pdu(action = "set", self_id = self.self_id, bsc_id = self.bsc_id, signing_cert = (bsc_ee,)))
rpki.log.info("Creating rpkid repository object for %s" % self.name)
self.repository_id = self.call_rpkid(rpki.left_right.repository_elt.make_pdu(action = "create", self_id = self.self_id, bsc_id = self.bsc_id)).repository_id
@@ -626,12 +621,12 @@ class allocation(object):
if self.is_root():
self.parent_id = self.call_rpkid(rpki.left_right.parent_elt.make_pdu(
action = "create", self_id = self.self_id, bsc_id = self.bsc_id, repository_id = self.repository_id, sia_base = self.sia_base,
- peer_biz_cert = rootd_ta, peer_biz_glue = rootd_ta, sender_name = self.name, recipient_name = "Walrus",
+ peer_biz_cert = rootd_ta, sender_name = self.name, recipient_name = "Walrus",
peer_contact_uri = "https://localhost:%s/" % rootd_port)).parent_id
else:
self.parent_id = self.call_rpkid(rpki.left_right.parent_elt.make_pdu(
action = "create", self_id = self.self_id, bsc_id = self.bsc_id, repository_id = self.repository_id, sia_base = self.sia_base,
- peer_biz_cert = self.parent.rpkid_ta, peer_biz_glue = self.parent.rpkid_ta, sender_name = self.name, recipient_name = self.parent.name,
+ peer_biz_cert = self.parent.rpkid_ta, sender_name = self.name, recipient_name = self.parent.name,
peer_contact_uri = "https://localhost:%s/up-down/%s" % (self.parent.rpki_port, self.child_id))).parent_id
rpki.log.info("Creating rpkid child objects for %s" % self.name)
@@ -649,8 +644,6 @@ class allocation(object):
action = "create", self_id = self.self_id, as_number = ro.asn,
exact_match = ro.exact_match, ipv4 = ro.v4, ipv6 = ro.v6)).route_origin_id
-# exact_match = 1 if ro.exact_match else 0
-
def write_leaf_yaml(self):
"""Write YAML scripts for leaf nodes. Only supports list requests
at the moment: issue requests would require class and SIA values,
@@ -675,8 +668,8 @@ class allocation(object):
"""Trigger cron run for this engine."""
rpki.log.info("Running cron for %s" % self.name)
- rpki.https.client(client_key = testbed_key,
- client_certs = testbed_certs,
+ rpki.https.client(client_key = self.irbe_key,
+ client_cert = self.irbe_cer,
server_ta = self.rpkid_ta,
url = "https://localhost:%d/cronjob" % self.rpki_port,
msg = "Run cron now, please")
@@ -687,13 +680,13 @@ class allocation(object):
subprocess.check_call((prog_python, prog_poke, "-y", self.name + ".yaml", "-r", "list", "-d"))
subprocess.check_call((prog_python, prog_poke, "-y", self.name + ".yaml", "-r", "issue", "-d"))
-def setup_biz_cert_chain(name):
+def setup_biz_cert_chain(name, ee = (), ca = ()):
"""Build a set of business certs."""
s = "exec >/dev/null 2>&1\n"
- for kind in ("EE", "CA", "TA"):
+ for kind in ("TA",) + ee + ca:
d = { "name" : name,
"kind" : kind,
- "ca" : "true" if kind in ("CA", "TA") else "false",
+ "ca" : "false" if kind in ee else "true",
"openssl" : prog_openssl }
f = open("%(name)s-%(kind)s.cnf" % d, "w")
f.write(biz_cert_fmt_1 % d)
@@ -701,15 +694,20 @@ def setup_biz_cert_chain(name):
if not os.path.exists("%(name)s-%(kind)s.key" % d):
s += biz_cert_fmt_2 % d
s += biz_cert_fmt_3 % d
- s += (biz_cert_fmt_4 % { "name" : name, "openssl" : prog_openssl })
+ d = { "name" : name, "openssl" : prog_openssl }
+ s += biz_cert_fmt_4 % d
+ for kind in ee + ca:
+ d["kind"] = kind
+ s += biz_cert_fmt_5 % d
subprocess.check_call(s, shell = True)
-def setup_rootd(rpkid_name):
+def setup_rootd(rpkid_name, rpkid_tag):
"""Write the config files for rootd."""
rpki.log.info("Writing config files for %s" % rootd_name)
d = { "rootd_name" : rootd_name,
"rootd_port" : rootd_port,
"rpkid_name" : rpkid_name,
+ "rpkid_tag" : rpkid_tag,
"rootd_sia" : rootd_sia,
"rsyncd_dir" : rsyncd_dir,
"openssl" : prog_openssl }
@@ -795,9 +793,12 @@ biz_cert_fmt_3 = '''\
'''
biz_cert_fmt_4 = '''\
-%(openssl)s x509 -req -in %(name)s-TA.req -out %(name)s-TA.cer -extfile %(name)s-TA.cnf -extensions req_x509_ext -signkey %(name)s-TA.key -days 60 &&
-%(openssl)s x509 -req -in %(name)s-CA.req -out %(name)s-CA.cer -extfile %(name)s-CA.cnf -extensions req_x509_ext -CA %(name)s-TA.cer -CAkey %(name)s-TA.key -CAcreateserial &&
-%(openssl)s x509 -req -in %(name)s-EE.req -out %(name)s-EE.cer -extfile %(name)s-EE.cnf -extensions req_x509_ext -CA %(name)s-CA.cer -CAkey %(name)s-CA.key -CAcreateserial
+%(openssl)s x509 -req -in %(name)s-TA.req -out %(name)s-TA.cer -extfile %(name)s-TA.cnf -extensions req_x509_ext -signkey %(name)s-TA.key -days 60 \
+'''
+
+biz_cert_fmt_5 = ''' && \
+%(openssl)s x509 -req -in %(name)s-%(kind)s.req -out %(name)s-%(kind)s.cer -extfile %(name)s-%(kind)s.cnf -extensions req_x509_ext -days 30 \
+ -CA %(name)s-TA.cer -CAkey %(name)s-TA.key -CAcreateserial \
'''
yaml_fmt_1 = '''---
@@ -838,31 +839,18 @@ startup-message = This is %(my_name)s irdbd
sql-database = %(irdb_db_name)s
sql-username = irdb
sql-password = %(irdb_db_pass)s
-
-cms-key = %(my_name)s-IRDB-EE.key
-cms-cert.0 = %(my_name)s-IRDB-EE.cer
-cms-cert.1 = %(my_name)s-IRDB-CA.cer
-cms-ta = %(my_name)s-RPKI-TA.cer
-
-https-key = %(my_name)s-IRDB-EE.key
-https-cert.0 = %(my_name)s-IRDB-EE.cer
-https-cert.1 = %(my_name)s-IRDB-CA.cer
-https-ta = %(my_name)s-RPKI-TA.cer
-
+bpki-ta = %(my_name)s-TA.cer
+rpkid-cert = %(my_name)s-RPKI.cer
+irdbd-cert = %(my_name)s-IRDB.cer
+irdbd-key = %(my_name)s-IRDB.key
https-url = https://localhost:%(irdb_port)d/
[irbe-cli]
-cms-key = %(testbed_name)s-EE.key
-cms-cert.0 = %(testbed_name)s-EE.cer
-cms-cert.1 = %(testbed_name)s-CA.cer
-cms-ta = %(my_name)s-RPKI-TA.cer
-
-https-key = %(testbed_name)s-EE.key
-https-cert.0 = %(testbed_name)s-EE.cer
-https-cert.1 = %(testbed_name)s-CA.cer
-https-ta = %(my_name)s-RPKI-TA.cer
-
+bpki-ta = %(my_name)s-TA.cer
+rpkid-cert = %(my_name)s-RPKI.cer
+irbe-cert = %(my_name)s-IRBE.cer
+irbe-key = %(my_name)s-IRBE.key
https-url = https://localhost:%(rpki_port)d/left-right
[rpkid]
@@ -873,12 +861,11 @@ sql-database = %(rpki_db_name)s
sql-username = rpki
sql-password = %(rpki_db_pass)s
-ee-key = %(my_name)s-RPKI-EE.key
-cert-chain.0 = %(my_name)s-RPKI-EE.cer
-cert-chain.1 = %(my_name)s-RPKI-CA.cer
-
-ta-irdb = %(my_name)s-IRDB-TA.cer
-ta-irbe = %(testbed_name)s-TA.cer
+bpki-ta = %(my_name)s-TA.cer
+rpkid-key = %(my_name)s-RPKI.key
+rpkid-cert = %(my_name)s-RPKI.cer
+irdb-cert = %(my_name)s-IRDB.cer
+irbe-cert = %(my_name)s-IRBE.cer
irdb-url = https://localhost:%(irdb_port)d/
@@ -890,15 +877,10 @@ rootd_fmt_1 = '''\
[rootd]
-cms-key = %(rootd_name)s-EE.key
-cms-cert.0 = %(rootd_name)s-EE.cer
-cms-cert.1 = %(rootd_name)s-CA.cer
-cms-ta = %(rpkid_name)s-RPKI-TA.cer
-
-https-key = %(rootd_name)s-EE.key
-https-cert.0 = %(rootd_name)s-EE.cer
-https-cert.1 = %(rootd_name)s-CA.cer
-https-ta = %(rpkid_name)s-RPKI-TA.cer
+bpki-ta = %(rootd_name)s-TA.cer
+rootd-bpki-cert = %(rootd_name)s-RPKI.cer
+rootd-bpki-key = %(rootd_name)s-RPKI.key
+child-bpki-cert = %(rootd_name)s-%(rpkid_name)s.cer
server-port = %(rootd_port)s
@@ -917,6 +899,8 @@ encrypt_key = no
distinguished_name = req_dn
req_extensions = req_x509_ext
prompt = no
+default_md = sha256
+default_days = 60
[req_dn]
CN = Completely Bogus Test Root (NOT FOR PRODUCTION USE)
@@ -936,7 +920,9 @@ rootd_fmt_2 = '''\
rootd_fmt_3 = '''\
%(openssl)s req -new -key %(rootd_name)s.key -out %(rootd_name)s.req -config %(rootd_name)s.conf -text &&
-%(openssl)s x509 -req -in %(rootd_name)s.req -out %(rootd_name)s.cer -outform DER -extfile %(rootd_name)s.conf -extensions req_x509_ext -signkey %(rootd_name)s.key -sha256
+%(openssl)s x509 -req -in %(rootd_name)s.req -out %(rootd_name)s.cer -outform DER -extfile %(rootd_name)s.conf -extensions req_x509_ext -signkey %(rootd_name)s.key &&
+%(openssl)s x509 -req -in %(rpkid_name)s-%(rpkid_tag)s.req -out %(rootd_name)s-%(rpkid_name)s.cer -extfile %(rootd_name)s.conf -extensions req_x509_ext \
+ -CA %(rootd_name)s-TA.cer -CAkey %(rootd_name)s-TA.key -CAcreateserial
'''
rcynic_fmt_1 = '''\
diff --git a/rpkid/testpoke.py b/rpkid/testpoke.py
index 8da1daac..0b31371b 100644
--- a/rpkid/testpoke.py
+++ b/rpkid/testpoke.py
@@ -75,7 +75,7 @@ def get_PEM(name, cls, y = yaml_data):
return None
def get_PEM_chain(name, cert = None):
- chain = rpki.x509.X509_chain()
+ chain = []
if cert is not None:
chain.append(cert)
if name in yaml_data:
@@ -93,7 +93,7 @@ def query_up_down(q_pdu):
der = rpki.https.client(
server_ta = https_ta,
client_key = https_key,
- client_certs = https_certs,
+ client_cert = https_certs,
msg = q_cms,
url = yaml_data["posturl"])
r_msg, r_xml = rpki.up_down.cms_msg.unwrap(der, cms_ta, pretty_print = True)