Justin Karneges <justin@affinix.com>
Date: January 1st, 2005
Here are some jots about a way to secure JEP-0065.
Initiator creates self-signed certificate, with appropriate properties as described in RFC 3920 (xmpp-core), Section 5.1, TLS Rule #8. It is ok to reuse a certificate for many connections, but it is advisable to not write it (nor the private key) to disk since it is intended to be temporary.
Certificate is included in the JEP-0065 iq-set. It must be in Base64'd DER format (PEM minus the header/footer) as a child of the <cert> element.
<iq type='set' from='initiator@host1/foo' to='target@host2/bar' id='initiate'>
<query xmlns='http://jabber.org/protocol/bytestreams' sid='mySID' mode='tcp'>
<streamhost jid='initiator@host1/foo' host='192.168.4.1' port='5086'/>
<streamhost jid='proxy.host3' host='24.24.24.1' port='7777'/>
<cert xmlns='bytestreams:secure'>
MIIDbjCCAtegAwIBAgIBADANBgkqhkiG9w0BAQQFADCBhzELMAkGA1UEBhMCVVMx
EzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNVBAcTBklydmluZTEYMBYGA1UEChMP
RXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtleGFtcGxlLmNvbTEiMCAGCSqGSIb3
DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbTAeFw0wMzA3MjQwNzMwMDBaFw0wMzA4
MjMwNzMwMDBaMIGHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEP
MA0GA1UEBxMGSXJ2aW5lMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNV
BAMTC2V4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu
Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCobzCF268K2sRp473gvBTT
4AgSL1kjeF8N57vxS1P8zWrWMXNs4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwW
WZToesxebu3m9VeA8dqWyOaUMjoxAcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8m
a+AAPByfTORbzpSTmXAQAwIDAQABo4HnMIHkMB0GA1UdDgQWBBTvFierzLmmYMq0
cB/+5rK1bNR56zCBtAYDVR0jBIGsMIGpgBTvFierzLmmYMq0cB/+5rK1bNR566GB
jaSBijCBhzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNV
BAcTBklydmluZTEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtl
eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbYIB
ADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGqGhXf7xNOnYNtFO7gz
K6RdZGHFI5q1DAEz4hhNBC9uElh32XGX4wN7giz3zLC8v9icL/W4ff/K5NDfv3Gf
gQe/+Wo9Be3H3ul6uwPPFnx4+PIOF2a5TW99H9smyxWdNjnFtcUte4al3RszcMWG
x3iqsWosGtj6F+ridmKoqKLu
</cert>
</query>
</iq>Upon receiving this request, the Target must create his own self-signed certificate (if he has not done so already) and reply with it in the iq-result.
<iq type='result' from='target@host2/bar' to='initiator@host1/foo' id='initiate'>
<query xmlns='http://jabber.org/protocol/bytestreams'>
<streamhost-used jid='proxy.host3'/>
<cert xmlns='bytestreams:secure'> ... </cert>
</query>
</iq>At this point there is an active JEP-0065 session and both sides have exchanged the temporary certificates. Now a TLS (in the case of TCP) or DTLS (in the case of UDP) session is started by the initiator, and the certificates received over Jabber must be considered ultimately trusted for this session. In the event of a security error, the JEP-0065 session should be ended.
Security note: the JEP-0065 session is just as secure as the Jabber path between the entities. If end-to-end security is desired, then clients need only to sign the JEP-0065 stanzas using appropriate stanza security, such as RFC 3923 (xmpp-e2e).
Question: What is the rationale for using a temporary certificate, when I might have a real one? Answer: to streamline the operation so that it is the same either way, especially considering most people won't have their own certificates for a long time (hence it is the greater use-case). Also, CAs might not allow personal certificates to be used for serving TLS, as that usually costs money. Creating a temporary certificate yourself that has no restrictions is a way to get around this.
Question 2: Why not use PSK if I don't have a cert? Answer: because PSK is a long ways away, and we want something that will work fine in existing systems (Java, C#, openssl, etc).