int SSL_renegotiate(SSL *s)
{
+ /*
+ * TODO(TLS1.3): Return an error for now. Perhaps we should do a KeyUpdate
+ * instead when we support that?
+ */
+ if (SSL_IS_TLS13(s))
+ return 0;
+
if (s->renegotiate == 0)
s->renegotiate = 1;
int SSL_renegotiate_abbreviated(SSL *s)
{
+ /*
+ * TODO(TLS1.3): Return an error for now. Perhaps we should do a KeyUpdate
+ * instead when we support that?
+ */
+ if (SSL_IS_TLS13(s))
+ return 0;
+
if (s->renegotiate == 0)
s->renegotiate = 1;
return -1;
}
- s->method->ssl_renegotiate_check(s);
+ s->method->ssl_renegotiate_check(s, 0);
if (SSL_in_init(s) || SSL_in_before(s)) {
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
/*
* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
* variable, freeing EVP_MD_CTX previously stored in that variable, if any.
- * If EVP_MD pointer is passed, initializes ctx with this md Returns newly
- * allocated ctx;
+ * If EVP_MD pointer is passed, initializes ctx with this md.
+ * Returns the newly allocated ctx;
*/
EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md)
}
#endif
+
+void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb)
+{
+ ctx->keylog_callback = cb;
+}
+
+SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx)
+{
+ return ctx->keylog_callback;
+}
+
+static int nss_keylog_int(const char *prefix,
+ SSL *ssl,
+ const uint8_t *parameter_1,
+ size_t parameter_1_len,
+ const uint8_t *parameter_2,
+ size_t parameter_2_len)
+{
+ char *out = NULL;
+ char *cursor = NULL;
+ size_t out_len = 0;
+ size_t i;
+ size_t prefix_len;
+
+ if (ssl->ctx->keylog_callback == NULL) return 1;
+
+ /*
+ * Our output buffer will contain the following strings, rendered with
+ * space characters in between, terminated by a NULL character: first the
+ * prefix, then the first parameter, then the second parameter. The
+ * meaning of each parameter depends on the specific key material being
+ * logged. Note that the first and second parameters are encoded in
+ * hexadecimal, so we need a buffer that is twice their lengths.
+ */
+ prefix_len = strlen(prefix);
+ out_len = prefix_len + (2*parameter_1_len) + (2*parameter_2_len) + 3;
+ if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) {
+ SSLerr(SSL_F_NSS_KEYLOG_INT, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ strcpy(cursor, prefix);
+ cursor += prefix_len;
+ *cursor++ = ' ';
+
+ for (i = 0; i < parameter_1_len; i++) {
+ sprintf(cursor, "%02x", parameter_1[i]);
+ cursor += 2;
+ }
+ *cursor++ = ' ';
+
+ for (i = 0; i < parameter_2_len; i++) {
+ sprintf(cursor, "%02x", parameter_2[i]);
+ cursor += 2;
+ }
+ *cursor = '\0';
+
+ ssl->ctx->keylog_callback(ssl, (const char *)out);
+ OPENSSL_free(out);
+ return 1;
+
+}
+
+int ssl_log_rsa_client_key_exchange(SSL *ssl,
+ const uint8_t *encrypted_premaster,
+ size_t encrypted_premaster_len,
+ const uint8_t *premaster,
+ size_t premaster_len)
+{
+ if (encrypted_premaster_len < 8) {
+ SSLerr(SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ /* We only want the first 8 bytes of the encrypted premaster as a tag. */
+ return nss_keylog_int("RSA",
+ ssl,
+ encrypted_premaster,
+ 8,
+ premaster,
+ premaster_len);
+}
+
+int ssl_log_master_secret(SSL *ssl,
+ const uint8_t *client_random,
+ size_t client_random_len,
+ const uint8_t *master,
+ size_t master_len)
+{
+ /*
+ * TLSv1.3 changes the derivation of the master secret compared to earlier
+ * TLS versions, meaning that logging it out is less useful. Instead we
+ * want to log out other secrets: specifically, the handshake and
+ * application traffic secrets. For this reason, if this function is called
+ * for TLSv1.3 we don't bother logging, and just return success
+ * immediately.
+ */
+ if (SSL_IS_TLS13(ssl)) return 1;
+
+ if (client_random_len != 32) {
+ SSLerr(SSL_F_SSL_LOG_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return nss_keylog_int("CLIENT_RANDOM",
+ ssl,
+ client_random,
+ client_random_len,
+ master,
+ master_len);
+}
+