summaryrefslogtreecommitdiffstats
path: root/ssl/t1_enc.c
diff options
context:
space:
mode:
authorBen Laurie <ben@openssl.org>2011-11-15 23:51:22 +0000
committerBen Laurie <ben@openssl.org>2011-11-15 23:51:22 +0000
commitb1d7429186658934e4ca8b7913c3640ef4426e45 (patch)
treebaa81aec5fc88283adf9389c7903eab77772dddc /ssl/t1_enc.c
parent060a38a2c06145df02d04af20e31bacf30f192e2 (diff)
Add TLS exporter.
Diffstat (limited to 'ssl/t1_enc.c')
-rw-r--r--ssl/t1_enc.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 3452b25c45..b9d0dd3757 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -1119,6 +1119,95 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
return(SSL3_MASTER_SECRET_SIZE);
}
+int tls1_export_keying_material(SSL *s, unsigned char *out, unsigned int olen,
+ const char *label, unsigned int llen, const unsigned char *context,
+ unsigned int contextlen, int use_context)
+ {
+ unsigned char *buff;
+ unsigned char *val;
+ unsigned int vallen, currentvalpos, rv;
+
+#ifdef KSSL_DEBUG
+ printf ("tls1_export_keying_material(%p, %p,%d, %s,%d, %p,%d)\n", s, out,olen, label,llen, p,plen);
+#endif /* KSSL_DEBUG */
+
+ buff = OPENSSL_malloc(olen);
+ if (buff == NULL) goto err2;
+
+ /* construct PRF arguments
+ * we construct the PRF argument ourself rather than passing separate
+ * values into the TLS PRF to ensure that the concatenation of values
+ * does not create a prohibited label.
+ */
+ vallen = llen + SSL3_RANDOM_SIZE * 2;
+ if (use_context)
+ {
+ vallen += 2 + contextlen;
+ }
+
+ val = OPENSSL_malloc(vallen);
+ if (val == NULL) goto err2;
+ currentvalpos = 0;
+ memcpy(val + currentvalpos, (unsigned char *) label, llen);
+ currentvalpos += llen;
+ memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
+ currentvalpos += SSL3_RANDOM_SIZE;
+ memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
+ currentvalpos += SSL3_RANDOM_SIZE;
+
+ if (use_context)
+ {
+ val[currentvalpos] = (contextlen << 8) & 0xff;
+ currentvalpos++;
+ val[currentvalpos] = contextlen & 0xff;
+ currentvalpos++;
+ if ((contextlen > 0) || (context != NULL))
+ {
+ memcpy(val + currentvalpos, context, contextlen);
+ }
+ }
+
+ /* disallow prohibited labels
+ * note that SSL3_RANDOM_SIZE > max(prohibited label len) =
+ * 15, so size of val > max(prohibited label len) = 15 and the
+ * comparisons won't have buffer overflow
+ */
+ if (bcmp(val, TLS_MD_CLIENT_FINISH_CONST,
+ TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) goto err1;
+ if (bcmp(val, TLS_MD_SERVER_FINISH_CONST,
+ TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) goto err1;
+ if (bcmp(val, TLS_MD_MASTER_SECRET_CONST,
+ TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) goto err1;
+ if (bcmp(val, TLS_MD_KEY_EXPANSION_CONST,
+ TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
+
+ tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ val, vallen,
+ NULL, 0,
+ NULL, 0,
+ NULL, 0,
+ NULL, 0,
+ s->session->master_key,s->session->master_key_length,
+ out,buff,olen);
+
+#ifdef KSSL_DEBUG
+ printf ("tls1_export_keying_material() complete\n");
+#endif /* KSSL_DEBUG */
+ rv = olen;
+ goto ret;
+err1:
+ SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
+ rv = 0;
+ goto ret;
+err2:
+ SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE);
+ rv = 0;
+ret:
+ if (buff != NULL) OPENSSL_free(buff);
+ if (val != NULL) OPENSSL_free(val);
+ return(rv);
+ }
+
int tls1_alert_code(int code)
{
switch (code)