summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2015-09-14 17:58:04 +0100
committerDr. Stephen Henson <steve@openssl.org>2015-09-14 19:52:27 +0100
commitdf6da24bda457b724ba3e894e6c329a9b93d536f (patch)
tree3296a79122416d0d6dd31c6268ad6c92ba2fa2f1 /ssl
parentaabd49232025807babe995006a46c4c7815ce868 (diff)
Fix PSK identity hint handling.
For server use a PSK identity hint value in the CERT structure which is inherited when SSL_new is called and which allows applications to set hints on a per-SSL basis. The previous version of SSL_use_psk_identity_hint tried (wrongly) to use the SSL_SESSION structure. PR#4039 Reviewed-by: Matt Caswell <matt@openssl.org>
Diffstat (limited to 'ssl')
-rw-r--r--ssl/d1_srvr.c2
-rw-r--r--ssl/s3_srvr.c16
-rw-r--r--ssl/ssl_cert.c9
-rw-r--r--ssl/ssl_lib.c22
-rw-r--r--ssl/ssl_locl.h5
5 files changed, 30 insertions, 24 deletions
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 555bbdfc11..f56bf5adef 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -478,7 +478,7 @@ int dtls1_accept(SSL *s)
* provided
*/
#ifndef OPENSSL_NO_PSK
- || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
+ || ((alg_k & SSL_kPSK) && s->cert->psk_identity_hint)
#endif
|| (alg_k & SSL_kDHE)
|| (alg_k & SSL_kECDHE)
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index ec09840d5b..e864ad1580 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -444,7 +444,7 @@ int ssl3_accept(SSL *s)
*/
#ifndef OPENSSL_NO_PSK
/* Only send SKE if we have identity hint for plain PSK */
- || ((alg_k & (SSL_kPSK | SSL_kRSAPSK)) && s->ctx->psk_identity_hint)
+ || ((alg_k & (SSL_kPSK | SSL_kRSAPSK)) && s->cert->psk_identity_hint)
/* For other PSK always send SKE */
|| (alg_k & (SSL_PSK & (SSL_kDHEPSK | SSL_kECDHEPSK)))
#endif
@@ -1708,8 +1708,8 @@ int ssl3_send_server_key_exchange(SSL *s)
* reserve size for record length and PSK identity hint
*/
n += 2;
- if (s->ctx->psk_identity_hint)
- n += strlen(s->ctx->psk_identity_hint);
+ if (s->cert->psk_identity_hint)
+ n += strlen(s->cert->psk_identity_hint);
}
/* Plain PSK or RSAPSK nothing to do */
if (type & (SSL_kPSK | SSL_kRSAPSK)) {
@@ -1991,11 +1991,11 @@ int ssl3_send_server_key_exchange(SSL *s)
#ifndef OPENSSL_NO_PSK
if (type & SSL_PSK) {
/* copy PSK identity hint */
- if (s->ctx->psk_identity_hint) {
- s2n(strlen(s->ctx->psk_identity_hint), p);
- strncpy((char *)p, s->ctx->psk_identity_hint,
- strlen(s->ctx->psk_identity_hint));
- p += strlen(s->ctx->psk_identity_hint);
+ if (s->cert->psk_identity_hint) {
+ s2n(strlen(s->cert->psk_identity_hint), p);
+ strncpy((char *)p, s->cert->psk_identity_hint,
+ strlen(s->cert->psk_identity_hint));
+ p += strlen(s->cert->psk_identity_hint);
} else {
s2n(0, p);
}
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 555b1d7d82..05a4447450 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -334,6 +334,12 @@ CERT *ssl_cert_dup(CERT *cert)
if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext))
goto err;
+ if (cert->psk_identity_hint) {
+ ret->psk_identity_hint = BUF_strdup(cert->psk_identity_hint);
+ if (ret->psk_identity_hint == NULL)
+ goto err;
+ }
+
return (ret);
err:
@@ -402,6 +408,9 @@ void ssl_cert_free(CERT *c)
X509_STORE_free(c->chain_store);
custom_exts_free(&c->cli_ext);
custom_exts_free(&c->srv_ext);
+#ifndef OPENSSL_NO_PSK
+ OPENSSL_free(c->psk_identity_hint);
+#endif
OPENSSL_free(c);
}
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index c5d4a8e250..28b71082ab 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1825,9 +1825,6 @@ void SSL_CTX_free(SSL_CTX *a)
#ifndef OPENSSL_NO_SRTP
sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
#endif
-#ifndef OPENSSL_NO_PSK
- OPENSSL_free(a->psk_identity_hint);
-#endif
#ifndef OPENSSL_NO_SRP
SSL_CTX_SRP_CTX_free(a);
#endif
@@ -3007,13 +3004,13 @@ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
- OPENSSL_free(ctx->psk_identity_hint);
+ OPENSSL_free(ctx->cert->psk_identity_hint);
if (identity_hint != NULL) {
- ctx->psk_identity_hint = BUF_strdup(identity_hint);
- if (ctx->psk_identity_hint == NULL)
+ ctx->cert->psk_identity_hint = BUF_strdup(identity_hint);
+ if (ctx->cert->psk_identity_hint == NULL)
return 0;
} else
- ctx->psk_identity_hint = NULL;
+ ctx->cert->psk_identity_hint = NULL;
return 1;
}
@@ -3022,20 +3019,17 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
if (s == NULL)
return 0;
- if (s->session == NULL)
- return 1; /* session not created yet, ignored */
-
if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
- OPENSSL_free(s->session->psk_identity_hint);
+ OPENSSL_free(s->cert->psk_identity_hint);
if (identity_hint != NULL) {
- s->session->psk_identity_hint = BUF_strdup(identity_hint);
- if (s->session->psk_identity_hint == NULL)
+ s->cert->psk_identity_hint = BUF_strdup(identity_hint);
+ if (s->cert->psk_identity_hint == NULL)
return 0;
} else
- s->session->psk_identity_hint = NULL;
+ s->cert->psk_identity_hint = NULL;
return 1;
}
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 2539a4e344..083ced3927 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -873,7 +873,6 @@ struct ssl_ctx_st {
void *tlsext_status_arg;
# ifndef OPENSSL_NO_PSK
- char *psk_identity_hint;
unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
char *identity,
unsigned int max_identity_len,
@@ -1592,6 +1591,10 @@ typedef struct cert_st {
/* Security level */
int sec_level;
void *sec_ex;
+#ifndef OPENSSL_NO_PSK
+ /* If not NULL psk identity hint to use for servers */
+ char *psk_identity_hint;
+#endif
int references; /* >1 only if SSL_copy_session_id is used */
} CERT;