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>
This commit is contained in:
parent
aabd492320
commit
df6da24bda
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user