From e681bc2125a396ff34aab4c3f629683dd0ce28bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Thu, 23 Apr 2015 20:59:30 +0200 Subject: [PATCH] Introduce TLS-RSA-PSK support Build on the existing PSK support and introduce RSA-PSK (cf. RFC 4279, 5487). Based on the original patch by Christian J. Dietrich. This work has been sponsored by Governikus GmbH & Co. KG. PR: 2464 --- doc/apps/ciphers.pod | 12 +++ ssl/s3_clnt.c | 106 ++++++++++++++++++++---- ssl/s3_lib.c | 206 +++++++++++++++++++++++++++++++++++++++++++++- ssl/s3_srvr.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++--- ssl/ssl.h | 2 + ssl/ssl_ciph.c | 9 +- ssl/ssl_lib.c | 6 ++ ssl/ssl_locl.h | 2 + ssl/tls1.h | 36 ++++++++ 9 files changed, 572 insertions(+), 33 deletions(-) diff --git x/doc/apps/ciphers.pod y/doc/apps/ciphers.pod index fa16124d08..45db06c168 100644 --- x/doc/apps/ciphers.pod +++ y/doc/apps/ciphers.pod @@ -585,10 +585,22 @@ Note: these ciphers can also be used in SSL v3. =head2 Pre shared keying (PSK) cipheruites + TLS_RSA_PSK_WITH_RC4_128_SHA RSA-PSK-RC4-SHA + TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA RSA-PSK-3DES-EDE-CBC-SHA + TLS_RSA_PSK_WITH_AES_128_CBC_SHA RSA-PSK-AES128-CBC-SHA + TLS_RSA_PSK_WITH_AES_256_CBC_SHA RSA-PSK-AES256-CBC-SHA + TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 RSA-PSK-AES128-CBC-SHA256 + TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 RSA-PSK-AES256-CBC-SHA384 + TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 RSA-PSK-AES128-GCM-SHA256 + TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 RSA-PSK-AES256-GCM-SHA384 TLS_PSK_WITH_RC4_128_SHA PSK-RC4-SHA TLS_PSK_WITH_3DES_EDE_CBC_SHA PSK-3DES-EDE-CBC-SHA TLS_PSK_WITH_AES_128_CBC_SHA PSK-AES128-CBC-SHA TLS_PSK_WITH_AES_256_CBC_SHA PSK-AES256-CBC-SHA + TLS_PSK_WITH_AES_128_CBC_SHA256 PSK-AES128-CBC-SHA256 + TLS_PSK_WITH_AES_256_CBC_SHA384 PSK-AES256-CBC-SHA384 + TLS_PSK_WITH_AES_128_GCM_SHA256 PSK-AES128-GCM-SHA256 + TLS_PSK_WITH_AES_256_GCM_SHA384 PSK-AES256-GCM-SHA384 =head2 Deprecated SSL v2.0 cipher suites. diff --git x/ssl/s3_clnt.c y/ssl/s3_clnt.c index 5b8b2da59f..ae0d4d840c 100644 --- x/ssl/s3_clnt.c +++ y/ssl/s3_clnt.c @@ -342,7 +342,7 @@ int ssl3_connect(SSL *s) } #endif /* Check if it is anon DH/ECDH, SRP auth */ - /* or PSK */ + /* or plain PSK */ if (! (s->s3->tmp. new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) @@ -1424,9 +1424,9 @@ int ssl3_get_key_exchange(SSL *s) } #ifndef OPENSSL_NO_PSK /* - * In plain PSK ciphersuite, ServerKeyExchange can be omitted if no - * identity hint is sent. Set session->sess_cert anyway to avoid - * problems later. + * In PSK ciphersuites, ServerKeyExchange can be omitted if no + * identity hint is sent. Set session->sess_cert for plain PSK + * anyway to avoid problems later. */ if (alg_k & SSL_kPSK) { s->session->sess_cert = ssl_sess_cert_new(); @@ -1471,7 +1471,12 @@ int ssl3_get_key_exchange(SSL *s) al = SSL_AD_DECODE_ERROR; #ifndef OPENSSL_NO_PSK - if (alg_k & SSL_kPSK) { + /* handle PSK identity hint */ + if (alg_k & SSL_kPSK +#ifndef OPENSSL_NO_RSA + || alg_k & SSL_kRSAPSK +#endif + ) { param_len = 2; if (param_len > n) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); @@ -2041,7 +2046,7 @@ int ssl3_get_key_exchange(SSL *s) } } else { /* aNULL, aSRP or kPSK do not need public keys */ - if (!(alg_a & (SSL_aNULL | SSL_aSRP)) && !(alg_k & SSL_kPSK)) { + if (!(alg_a & (SSL_aNULL | SSL_aSRP)) && !(alg_k & SSL_kPSK) && !(alg_k & SSL_kRSAPSK)) { /* Might be wrong key type, check it */ if (ssl3_check_cert_and_algorithm(s)) /* Otherwise this shouldn't happen */ @@ -3130,7 +3135,11 @@ int ssl3_send_client_key_exchange(SSL *s) } #endif #ifndef OPENSSL_NO_PSK - else if (alg_k & SSL_kPSK) { + else if (alg_k & SSL_kPSK +#ifndef OPENSSL_NO_RSA + || alg_k & SSL_kRSAPSK +#endif + ) { /* * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a * \0-terminated identity. The last byte is for us for simulating @@ -3138,8 +3147,8 @@ int ssl3_send_client_key_exchange(SSL *s) */ char identity[PSK_MAX_IDENTITY_LEN + 2]; size_t identity_len; - unsigned char *t = NULL; unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; + unsigned char *t = psk_or_pre_ms; unsigned int pre_ms_len = 0, psk_len = 0; int psk_err = 1; @@ -3171,14 +3180,34 @@ int ssl3_send_client_key_exchange(SSL *s) ERR_R_INTERNAL_ERROR); goto psk_err; } - /* create PSK pre_master_secret */ - pre_ms_len = 2 + psk_len + 2 + psk_len; - t = psk_or_pre_ms; - memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); - s2n(psk_len, t); - memset(t, 0, psk_len); - t += psk_len; - s2n(psk_len, t); + + if (alg_k & SSL_kPSK) { + /* create PSK pre_master_secret */ + pre_ms_len = 2 + psk_len + 2 + psk_len; + memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t += psk_len; + s2n(psk_len, t); + } +#ifndef OPENSSL_NO_RSA + else if (alg_k & SSL_kRSAPSK) { + const unsigned int pre_ms_prefix = 48; + + pre_ms_len = 2 + 2 + 46 + 2 + psk_len; + memmove(psk_or_pre_ms + 52, psk_or_pre_ms, psk_len); + s2n(pre_ms_prefix, t); + + psk_or_pre_ms[2] = s->client_version >> 8; + psk_or_pre_ms[3] = s->client_version & 0xff; + t += 2; + + if (RAND_bytes(psk_or_pre_ms + 4, 46) <= 0) + goto psk_err; + t += 46; + s2n(psk_len, t); + } +#endif if (s->session->psk_identity_hint != NULL) OPENSSL_free(s->session->psk_identity_hint); @@ -3208,8 +3237,41 @@ int ssl3_send_client_key_exchange(SSL *s) pre_ms_len); s2n(identity_len, p); memcpy(p, identity, identity_len); + p += identity_len; n = 2 + identity_len; + +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSAPSK) { + RSA *rsa; + int enc_n; + + if (s->session->sess_cert->peer_rsa_tmp != NULL) { + rsa = s->session->sess_cert->peer_rsa_tmp; + } else { + pkey = X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); + if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto psk_err; + } + rsa = pkey->pkey.rsa; + EVP_PKEY_free(pkey); + } + + enc_n = RSA_public_encrypt(48, psk_or_pre_ms + 2, p + 2, rsa, RSA_PKCS1_PADDING); + if (enc_n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_BAD_RSA_ENCRYPT); + goto psk_err; + } + + n += enc_n; + + s2n(enc_n, p); + n += 2; + } +#endif + psk_err = 0; + psk_err: OPENSSL_cleanse(identity, sizeof(identity)); OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); @@ -3580,7 +3642,11 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #endif #ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { + if (alg_k & SSL_kRSA +#ifndef OPENSSL_NO_PSK + || alg_k & SSL_kRSAPSK +#endif + ) { if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, @@ -3647,7 +3713,11 @@ int ssl3_check_cert_and_algorithm(SSL *s) if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { #ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { + if (alg_k & SSL_kRSA +#ifndef OPENSSL_NO_PSK + || alg_k & SSL_kRSAPSK +#endif + ) { if (rsa == NULL) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_EXPORT_TMP_RSA_KEY); diff --git x/ssl/s3_lib.c y/ssl/s3_lib.c index 1014a3fce1..0187d508a1 100644 --- x/ssl/s3_lib.c +++ y/ssl/s3_lib.c @@ -1765,6 +1765,74 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, + + +#ifndef OPENSSL_NO_RSA + /* RSA-PSK ciphersuites from RFC4279 */ + /* Cipher 92 */ + { + 1, + TLS1_TXT_RSA_PSK_WITH_RC4_128_SHA, + TLS1_CK_RSA_PSK_WITH_RC4_128_SHA, + SSL_kRSAPSK, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 93 */ + { + 1, + TLS1_TXT_RSA_PSK_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA, + SSL_kRSAPSK, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 112, + 168, + }, + + /* Cipher 94 */ + { + 1, + TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA, + TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA, + SSL_kRSAPSK, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 128, + 128, + }, + + /* Cipher 95 */ + { + 1, + TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA, + TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA, + SSL_kRSAPSK, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_RSA */ #endif /* OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_SEED @@ -2077,6 +2145,142 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { 0}, #endif +#ifndef OPENSSL_NO_PSK + /* PSK ciphersuites from RFC5487 */ + + /* Cipher A8 */ + { + 1, + TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256, + TLS1_CK_PSK_WITH_AES_128_GCM_SHA256, + SSL_kPSK, + SSL_aPSK, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A9 */ + { + 1, + TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384, + TLS1_CK_PSK_WITH_AES_256_GCM_SHA384, + SSL_kPSK, + SSL_aPSK, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + 256, + 256, + }, + + #ifndef OPENSSL_NO_RSA + /* Cipher AC */ + { + 1, + TLS1_TXT_RSA_PSK_WITH_AES_128_GCM_SHA256, + TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256, + SSL_kRSAPSK, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher AD */ + { + 1, + TLS1_TXT_RSA_PSK_WITH_AES_256_GCM_SHA384, + TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384, + SSL_kRSAPSK, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + 256, + 256, + }, +#endif /* OPENSSL_NO_RSA */ + + /* Cipher AE */ + { + 1, + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA256, + TLS1_CK_PSK_WITH_AES_128_CBC_SHA256, + SSL_kPSK, + SSL_aPSK, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher AF */ + { + 1, + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA384, + TLS1_CK_PSK_WITH_AES_256_CBC_SHA384, + SSL_kPSK, + SSL_aPSK, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + 256, + 256, + }, + + #ifndef OPENSSL_NO_RSA + /* Cipher B6 */ + { + 1, + TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256, + TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256, + SSL_kRSAPSK, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher B7 */ + { + 1, + TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA384, + TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384, + SSL_kRSAPSK, + SSL_aRSA, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, + 256, + 256, + }, +#endif /* OPENSSL_NO_RSA */ +#endif /* OPENSSL_NO_PSK */ + #ifndef OPENSSL_NO_ECDH /* Cipher C001 */ { @@ -4169,7 +4373,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, #endif /* OPENSSL_NO_KRB5 */ #ifndef OPENSSL_NO_PSK /* with PSK there must be server callback set */ - if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL) + if ((alg_k & SSL_kPSK || alg_k & SSL_kRSAPSK) && s->psk_server_callback == NULL) continue; #endif /* OPENSSL_NO_PSK */ diff --git x/ssl/s3_srvr.c y/ssl/s3_srvr.c index 0fb4845d44..3498836e7d 100644 --- x/ssl/s3_srvr.c +++ y/ssl/s3_srvr.c @@ -467,19 +467,22 @@ int ssl3_accept(SSL *s) /* * only send if a DH key exchange, fortezza or RSA but we have a - * sign only certificate PSK: may send PSK identity hints For - * ECC ciphersuites, we send a serverKeyExchange message only if + * sign only certificate + * + * PSK|RSAPSK: may send PSK identity hints. + * Send ServerKeyExchange if PSK identity hint is provided. + * + * For ECC ciphersuites, we send a serverKeyExchange message only if * the cipher suite is either ECDH-anon or ECDHE. In other cases, * the server certificate contains the server's public key for * key exchange. */ if (0 - /* - * PSK: send ServerKeyExchange if PSK identity hint if - * provided - */ #ifndef OPENSSL_NO_PSK - || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) + || (alg_k & SSL_kPSK && s->ctx->psk_identity_hint) +#ifndef OPENSSL_NO_RSA + || (alg_k & SSL_kRSAPSK && s->ctx->psk_identity_hint) +#endif #endif #ifndef OPENSSL_NO_SRP /* SRP: send ServerKeyExchange */ @@ -535,11 +538,14 @@ int ssl3_accept(SSL *s) (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) || /* don't request certificate for SRP auth */ (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP) +#ifndef OPENSSL_NO_PSK /* - * With normal PSK Certificates and Certificate Requests + * With normal PSK, Certificates and Certificate Requests * are omitted */ - || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) +#endif + ) { /* no cert request */ skip = 1; s->s3->tmp.cert_request = 0; @@ -1835,7 +1841,11 @@ int ssl3_send_server_key_exchange(SSL *s) } else #endif /* !OPENSSL_NO_ECDH */ #ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) { + if (type & SSL_kPSK +#ifndef OPENSSL_NO_RSA + || type & SSL_kRSAPSK +#endif + ) { /* * reserve size for record length and PSK identity hint */ @@ -1884,7 +1894,8 @@ int ssl3_send_server_key_exchange(SSL *s) } if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSAPSK)) { if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md)) == NULL) { al = SSL_AD_DECODE_ERROR; @@ -1899,6 +1910,12 @@ int ssl3_send_server_key_exchange(SSL *s) } else { pkey = NULL; kn = 0; + /* Allow space for signature algorithm */ + if (SSL_USE_SIGALGS(s)) { + kn += 4; + const unsigned char *sig; + kn += tls12_get_psigalgs(s, 1, &sig); + } } if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) { @@ -1958,7 +1975,11 @@ int ssl3_send_server_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) { + if (type & SSL_kPSK +#ifndef OPENSSL_NO_RSA + || type & SSL_kRSAPSK +#endif + ) { /* copy PSK identity hint */ s2n(strlen(s->ctx->psk_identity_hint), p); strncpy((char *)p, s->ctx->psk_identity_hint, @@ -1974,7 +1995,11 @@ int ssl3_send_server_key_exchange(SSL *s) * points to the space at the end. */ #ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { + if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s) +#ifndef OPENSSL_NO_PSK + && !(type & SSL_kRSAPSK) +#endif + ) { q = md_buf; j = 0; for (num = 2; num > 0; num--) { @@ -2870,6 +2895,181 @@ int ssl3_get_client_key_exchange(SSL *s) goto f_err; } else #endif +#ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kRSAPSK) { + unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + int decrypt_len; + unsigned char decrypt_good, version_good; + unsigned char *orig_p = p; + + unsigned int psk_len; + + const unsigned int pre_master_secret_prefix = 48; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; + unsigned int pre_ms_len; + unsigned char *t = psk_or_pre_ms; + + char identity[PSK_MAX_IDENTITY_LEN + 1]; + int identity_len; + + int epms_len; + int psk_err = 1; + + /* No server callback? Bail out */ + if (s->psk_server_callback == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_PSK_NO_SERVER_CB); + goto f_err; + } + + /* FIX THIS UP EAY EAY EAY EAY */ + if (s->s3->tmp.use_rsa_tmp) { + if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL)) + rsa=s->cert->rsa_tmp; + /* + * Don't do a callback because rsa_tmp should be sent already + */ + if (rsa == NULL) { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_RSA_PKEY); + goto f_err; + } + } else { + pkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; + if ((pkey == NULL) || + (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_RSA_CERTIFICATE); + goto f_err; + } + rsa = pkey->pkey.rsa; + } + + /* Extract the PSK identity */ + if (n < (2 + 2)) { /* 2 bytes for the identity len, 2 bytes for the epms len */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + n2s(p, identity_len); + + if (identity_len > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + + if (n < (2 + identity_len + 2)) { /* as above, plus the identity len */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + memset(identity, 0, sizeof(identity)); + memcpy(identity, p, identity_len); + p += identity_len; + + /* fill the pre master secret with random bytes */ + if (RAND_pseudo_bytes(psk_or_pre_ms, sizeof(psk_or_pre_ms)) <= 0) + goto err; + + /* read the psk (into the beginning of the psk_or_pre_ms buffer */ + psk_len = s->psk_server_callback(s, identity, psk_or_pre_ms, sizeof(psk_or_pre_ms)); + + if (psk_len > PSK_MAX_PSK_LEN) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto rsapsk_err; + } else if (psk_len == 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + al=SSL_AD_UNKNOWN_PSK_IDENTITY; + goto rsapsk_err; + } + + /* move on onto decoding the 48 encrypted bytes */ + + /* how many bytes to decode? */ + n2s(p, epms_len); + + if (n != (2 + identity_len + 2 + epms_len)) { /* as above */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_LENGTH_MISMATCH); + goto rsapsk_err; + } + + /* decode in place into p */ + decrypt_len = RSA_private_decrypt(epms_len, p, p, rsa, RSA_PKCS1_PADDING); + decrypt_good = constant_time_eq_int_8(decrypt_len, 48); + + /* check the version sent by the client */ + version_good = constant_time_eq_8(p[0], (unsigned)(s->client_version>>8)); + version_good &= constant_time_eq_8(p[1], (unsigned)(s->client_version&0xff)); + + decrypt_good &= version_good; + + for (i = 0; i < (int) sizeof(rand_premaster_secret); i++) + p[i] = constant_time_select_8(decrypt_good, p[i], rand_premaster_secret[i]); + + /* + * build the pre master secret. it should look like this: + * 48 (2b) + version (2b) + random (46b) + psk_len (2b) + psk + */ + pre_ms_len = 2 + 2 + 46 + 2 + psk_len; + + /* the PSK is at the beginning of psk_or_pre_ms, move at the end */ + memmove(psk_or_pre_ms + 52, psk_or_pre_ms, psk_len); + + /* fill the "48" in */ + s2n(pre_master_secret_prefix, t); + + /* fill the 2 bytes version + the 46 random bytes (decrypted earlier with RSA) */ + memcpy(t, p, 48); + t += 48; + + /* fill the psk_len */ + s2n(psk_len, t); + + /* psk_or_pre_ms now contains the pre master secret */ + + /* set the identity in the session */ + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + + s->session->psk_identity = BUF_strdup(identity); + OPENSSL_cleanse(identity, sizeof(identity)); + + if (s->session->psk_identity == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto rsapsk_err; + } + + /* set the identity hint in the session */ + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL && s->session->psk_identity_hint == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto rsapsk_err; + } + + /* set the premaster key */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, + psk_or_pre_ms, pre_ms_len); + + psk_err = 0; + rsapsk_err: + OPENSSL_cleanse(orig_p, n); /* clear the whole payload area */ + if (psk_err != 0) + goto f_err; + } else +#endif +#endif #ifndef OPENSSL_NO_SRP if (alg_k & SSL_kSRP) { int param_len; diff --git x/ssl/ssl.h y/ssl/ssl.h index 90aeb0ce4e..78cf2212ed 100644 --- x/ssl/ssl.h +++ y/ssl/ssl.h @@ -254,6 +254,7 @@ extern "C" { # define SSL_TXT_kEECDH "kEECDH" # define SSL_TXT_kECDHE "kECDHE"/* alias for kEECDH */ # define SSL_TXT_kPSK "kPSK" +# define SSL_TXT_kRSAPSK "kRSAPSK" # define SSL_TXT_kGOST "kGOST" # define SSL_TXT_kSRP "kSRP" @@ -282,6 +283,7 @@ extern "C" { # define SSL_TXT_ECDSA "ECDSA" # define SSL_TXT_KRB5 "KRB5" # define SSL_TXT_PSK "PSK" +# define SSL_TXT_RSAPSK "RSAPSK" # define SSL_TXT_SRP "SRP" # define SSL_TXT_DES "DES" diff --git x/ssl/ssl_ciph.c y/ssl/ssl_ciph.c index ccdf00fa1b..19c4ac0656 100644 --- x/ssl/ssl_ciph.c +++ y/ssl/ssl_ciph.c @@ -263,6 +263,7 @@ static const SSL_CIPHER cipher_aliases[] = { 0, 0, 0}, {0, SSL_TXT_kPSK, 0, SSL_kPSK, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kRSAPSK, 0, SSL_kRSAPSK, 0, 0, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_kSRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_kGOST, 0, SSL_kGOST, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -294,6 +295,7 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_ADH, 0, SSL_kEDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_AECDH, 0, SSL_kEECDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_PSK, 0, SSL_kPSK, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_RSAPSK, 0, SSL_kRSAPSK, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_SRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, /* symmetric encryption aliases */ @@ -756,7 +758,7 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, *auth |= SSL_aECDH; #endif #ifdef OPENSSL_NO_PSK - *mkey |= SSL_kPSK; + *mkey |= SSL_kPSK | SSL_kRSAPSK; *auth |= SSL_aPSK; #endif #ifdef OPENSSL_NO_SRP @@ -1555,6 +1557,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK */ ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kRSAPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); ssl_cipher_apply_rule(0, SSL_kKRB5, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, @@ -1731,6 +1735,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kPSK: kx = "PSK"; break; + case SSL_kRSAPSK: + kx = "RSAPSK"; + break; case SSL_kSRP: kx = "SRP"; break; diff --git x/ssl/ssl_lib.c y/ssl/ssl_lib.c index 3539f4b8d2..df6a45bdc4 100644 --- x/ssl/ssl_lib.c +++ y/ssl/ssl_lib.c @@ -2442,8 +2442,14 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) #ifndef OPENSSL_NO_PSK mask_k |= SSL_kPSK; +#ifndef OPENSSL_NO_RSA + mask_k |= SSL_kRSAPSK; +#endif mask_a |= SSL_aPSK; emask_k |= SSL_kPSK; +#ifndef OPENSSL_NO_RSA + emask_k |= SSL_kRSAPSK; +#endif emask_a |= SSL_aPSK; #endif diff --git x/ssl/ssl_locl.h y/ssl/ssl_locl.h index aeffc00634..25b9f1d5b1 100644 --- x/ssl/ssl_locl.h +++ y/ssl/ssl_locl.h @@ -314,6 +314,8 @@ # define SSL_kGOST 0x00000200L /* SRP */ # define SSL_kSRP 0x00000400L +/* RSA PSK */ +# define SSL_kRSAPSK 0x00000800L /* Bits for algorithm_auth (server authentication) */ /* RSA auth */ diff --git x/ssl/tls1.h y/ssl/tls1.h index dd1d8c109e..e04e7ddabc 100644 --- x/ssl/tls1.h +++ y/ssl/tls1.h @@ -410,6 +410,24 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) # define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C # define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D +/* PSK ciphersuites from 5487 */ +# define TLS1_CK_PSK_WITH_AES_128_GCM_SHA256 0x030000A8 +# define TLS1_CK_PSK_WITH_AES_256_GCM_SHA384 0x030000A9 +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA256 0x030000AE +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA384 0x030000AF + +/* RSA-PSK ciphersuites from 4279 */ +# define TLS1_CK_RSA_PSK_WITH_RC4_128_SHA 0x03000092 +# define TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x03000093 +# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA 0x03000094 +# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA 0x03000095 + +/* RSA-PSK ciphersuites from 5487 */ +# define TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256 0x030000AC +# define TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384 0x030000AD +# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256 0x030000B6 +# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384 0x030000B7 + /* * Additional TLS ciphersuites from expired Internet Draft * draft-ietf-tls-56-bit-ciphersuites-01.txt (available if @@ -629,6 +647,24 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) # define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" # define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" +/* PSK ciphersuites from RFC 5487 */ +# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256 "PSK-AES128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384 "PSK-AES256-GCM-SHA384" +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA256 "PSK-AES128-CBC-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA384 "PSK-AES256-CBC-SHA384" + +/* RSA-PSK ciphersuites from RFC 4279 */ +# define TLS1_TXT_RSA_PSK_WITH_RC4_128_SHA "RSA-PSK-RC4-SHA" +# define TLS1_TXT_RSA_PSK_WITH_3DES_EDE_CBC_SHA "RSA-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA "RSA-PSK-AES128-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA "RSA-PSK-AES256-CBC-SHA" + +/* RSA-PSK ciphersuites from RFC 5487 */ +# define TLS1_TXT_RSA_PSK_WITH_AES_128_GCM_SHA256 "RSA-PSK-AES128-GCM-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_GCM_SHA384 "RSA-PSK-AES256-GCM-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256 "RSA-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA384 "RSA-PSK-AES256-CBC-SHA384" + /* SRP ciphersuite from RFC 5054 */ # define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" # define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" -- 2.15.0