--- /dev/null
+# Kerberos and the TLS Pool
+
+> *We have started to integrate Kerberos into the TLS Pool, but for now it is
+> a bit crude. We haven't yet established how to distribute responsibilities.*
+
+The integration of
+[TLS-KDH](https://tools.ietf.org/html/draft-vanrein-tls-kdh)
+into the TLS Pool is a major contribution towards a secure, yet fast
+Internet. It combines fluently with our sub-projects on
+[realm crossover](http://realm-xover.arpa2.net/kerberos.html)
+and
+[bring your own identity](http://internetwide.org/blog/2015/04/22/id-2-byoid.html)
+combined with
+[authorisation](http://internetwide.org/blog/2015/04/25/id-5-ksaml.html)
+for privacy in spite of
+[hosting-market specialisation](http://internetwide.org/blog/2014/11/19/back-to-hosting.html).
+Yeah, we have a
+[pretty big plan](http://internetwide.org/blog/2016/06/24/iwo-phases.html)
+on where to take the Internet!
+
+The matter with Kerberos is mainly who should hold the ticket cache being
+used. There are two basic possibilities, it could be made internal to the
+TLS Pool, or it could be externally provided over a new API.
+
+When we choose to use a new API for Kerberos it
+may or may not integrate with the user's desktop. Very often, desktops
+can hold Kerberos credentials or they can easily have them added, sometimes
+even united with the desktop login (and screensaver-protected) session.
+Moreover, the desktop is the place where the user might switch the primary
+identity being used.
+
+The alternative is to let the TLS Pool hold the Kerberos credentials for
+a user, and that would allow the integration of PKCS #11 in the sign-up
+process, which is specifically interesting in relation to PKINIT.
+
+The matters that help to decide on this are:
+
+ * The desktop location would require the
+ [new socket protocol](socketprotocol.rst)
+ because Kerberos tickets can grow larger than what we have fixed-allocated.
+ * Whether PKINIT is a good idea depends on what is the "security foundation";
+ is it Kerberos, or is it PKCS #11 -- because each can cause the other to
+ be created. We should even ask ourselves if the TLS Pool should make this
+ choice, or be supportive to both. Desktops and mobile stations may need
+ to make different choices, for example.
+
+At present, the crude implementation of Kerberos involves using the PIN
+request to obtain a Kerberos password; this means that it must be entered
+manually *or* that the Kerberos password should match the configuration
+file's fixed PIN setting `pkcs11_pin`. Clearly, the choice of layering
+one mechanism on top of the other has not yet been forced and so we are
+dealing with this kludge for now.
+
} else {
//
// For KDH-Only, the server supplies one of:
- // - an empty ticket (0 bytes long)
- // - a TGT for user-to-user mode (where considered useful)
+ // - a TGT for user-to-user mode (for p2p exchanges)
+ // - an DER NULL to waive u2u mode
//TODO// E_g2e ("MOVED: Failed to import Kerberos ticket",
//TODO// gnutls_pcert_import_krb_raw (
//TODO// *pcert,
// u2u = u2u || "shaken hands on TLS symmetry extension"
u2u = u2u && got_cc_srv; // We may simply not be able!
//
- // When not in user-to-user mode, deliver 0 bytes
+ // When not in user-to-user mode, deliver DER NULL
if (!u2u) {
- certdatum.data = "";
- certdatum.size = 0;
+ certdatum.data = "\x05\x00";
+ certdatum.size = 2;
E_g2e ("Failed to withhold Kerberos server ticket",
gnutls_pcert_import_krb_raw (
*pcert,
(const dercursor *) &auth,
NULL // Measure length, no output yet
);
- uint8_t *decptr = malloc (declen);
+ uint8_t *decptr = gnutls_malloc (declen);
if (decptr == NULL) {
return GNUTLS_E_MEMORY_ERROR;
}
cmd->krb_key.enctype,
declen,
&rawlen)) {
- free (decptr);
+ gnutls_free (decptr);
return GNUTLS_E_ENCRYPTION_FAILED;
}
- uint8_t *rawptr = malloc (rawlen);
+ uint8_t *rawptr = gnutls_malloc (rawlen);
if (rawptr == NULL) {
- free (decptr);
+ gnutls_free (decptr);
return GNUTLS_E_MEMORY_ERROR;
}
krb5_data decdata;
NULL,
&decdata,
&rawdata)) {
- free (rawptr);
- free (decptr);
+ gnutls_free (rawptr);
+ gnutls_free (decptr);
return GNUTLS_E_ENCRYPTION_FAILED;
}
//
QDERBUF_INT32_T deretype;
QDERBUF_UINT32_T derkvno;
encrypted_data_t encdata;
+ memset (&encdata, 0, sizeof (encdata));
encdata.etype = qder2b_pack_int32 (deretype, cmd->krb_key.enctype);
//NOT// encdata.kvno = qder2b_pack_int32 (derkvno, cmd->krb_key.kvno);
encdata.cipher.derptr = rawdata.ciphertext.data;
(const dercursor *) &encdata,
NULL // Measure length, no output yet
);
- uint8_t *encptr = malloc (enclen);
+ uint8_t *encptr = gnutls_malloc (enclen);
if (encptr == NULL) {
- free (rawptr);
- free (decptr);
+ gnutls_free (rawptr);
+ gnutls_free (decptr);
return GNUTLS_E_MEMORY_ERROR;
}
der_pack ( encdata_packer,
(const dercursor *) &encdata,
encptr + enclen);
- free (rawptr);
+ gnutls_free (rawptr);
//
// Return our final verdict on the generation of the Authenticator
dec_authenticator->data = decptr;
dercursor enctransport;
enctransport.derptr = enc_authenticator->data;
enctransport.derlen = enc_authenticator->size;
+prangefull ("EncData2unpack", enctransport.derptr, enctransport.derlen);
memset (&encdata, 0, sizeof (encdata));
if (0 != der_unpack ( &enctransport,
encdata_packer,
#ifdef HAVE_TLS_KDH
cmd->remote_cert_type = gnutls_certificate_type_get_peers (cmd->session);
certs = gnutls_certificate_get_peers (cmd->session, &num_certs);
+ // Note: server's certs _may_ be DER NULL due to mutual auth in Kerberos
#else
cmd->remote_cert_type = gnutls_certificate_type_get (cmd->session);
certs = gnutls_certificate_get (cmd->session, &num_certs);