Hello, I recently started working on this patch, rebasing it on latest master, cleaning it up (f.i. unifying some code paths where possible, to avoid duplicating code), completing the support for the other RSA-PSK ciphersuites defined by RFC 4279 and so on.
I'm attaching the version I'm working on, I will be glad if anyone could give some feedback (any sorts -- obvious mistakes, code policy violations, code style issues, etc.). Thanks! -- Giuseppe D'Angelo | [email protected] | Software Engineer KDAB (UK) Ltd., a KDAB Group company Tel. UK +44-1738-450410, Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-independent software solutions
>From f8e352542c54e412103de5410604958b99bd197e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo <[email protected]> Date: Sat, 8 Nov 2014 20:44:23 +0100 Subject: [PATCH] Introduce TLS-RSA-PSK support Build on the existing PSK support and introduce RSA-PSK (cf. RFC 4279). Based on the original patch by Christian J. Dietrich This work has been sponsored by Governikus GmbH & Co. KG. PR: 2464 --- CHANGES | 3 + doc/apps/ciphers.pod | 4 + ssl/s3_clnt.c | 109 ++++++++++++++++++++----- ssl/s3_lib.c | 69 +++++++++++++++- ssl/s3_srvr.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++--- ssl/ssl.h | 4 +- ssl/ssl_ciph.c | 16 ++-- ssl/ssl_lib.c | 6 ++ ssl/ssl_locl.h | 1 + ssl/tls1.h | 12 +++ 10 files changed, 403 insertions(+), 37 deletions(-) diff --git a/CHANGES b/CHANGES index d90febc..8b48914 100644 --- a/CHANGES +++ b/CHANGES @@ -303,6 +303,9 @@ whose return value is often ignored. [Steve Henson] + *) Support for TLS-RSA-PSK ciphersuites has been added. + [Giuseppe D'Angelo, Christian J. Dietrich] + Changes between 1.0.1j and 1.0.2 [xx XXX xxxx] *) Tighten client-side session ticket handling during renegotiation: diff --git a/doc/apps/ciphers.pod b/doc/apps/ciphers.pod index c41a297..f43abff 100644 --- a/doc/apps/ciphers.pod +++ b/doc/apps/ciphers.pod @@ -600,6 +600,10 @@ 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_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 diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 68c00c5..5fc5f1a 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -343,7 +343,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)) && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { @@ -1417,9 +1417,9 @@ int ssl3_get_key_exchange(SSL *s) if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { #ifndef OPENSSL_NO_PSK - /* In plain PSK ciphersuite, ServerKeyExchange can be + /* In PSK ciphersuites, ServerKeyExchange can be omitted if no identity hint is sent. Set - session->sess_cert anyway to avoid problems + session->sess_cert for plain PSK anyway to avoid problems later.*/ if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) { @@ -1473,7 +1473,8 @@ 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|SSL_kRSAPSK)) { char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1]; @@ -1650,7 +1651,7 @@ int ssl3_get_key_exchange(SSL *s) else #endif /* !OPENSSL_NO_SRP */ #ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) + if (alg_k & (SSL_kRSA|SSL_kRSAPSK)) { if ((rsa=RSA_new()) == NULL) { @@ -2061,8 +2062,8 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); } else { - /* aNULL, aSRP or kPSK do not need public keys */ - if (!(alg_a & (SSL_aNULL|SSL_aSRP)) && !(alg_k & SSL_kPSK)) + /* aNULL, aSRP, kPSK or kRSAPSK do not need public keys */ + if (!(alg_a & (SSL_aNULL|SSL_aSRP)) && !(alg_k & (SSL_kPSK|SSL_kRSAPSK))) { /* Might be wrong key type, check it */ if (ssl3_check_cert_and_algorithm(s)) @@ -2540,7 +2541,7 @@ int ssl3_send_client_key_exchange(SSL *s) rsa=pkey->pkey.rsa; EVP_PKEY_free(pkey); } - + tmp_buf[0]=s->client_version>>8; tmp_buf[1]=s->client_version&0xff; if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0) @@ -3132,15 +3133,19 @@ 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 strnlen. */ 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; @@ -3176,14 +3181,36 @@ 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); @@ -3210,10 +3237,52 @@ int ssl3_send_client_key_exchange(SSL *s) s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, psk_or_pre_ms, 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); + fprintf(stderr, "***\nENCRYPTED %d BYTES USING RSA_public_encrypt\n***\n", enc_n); + 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)); @@ -3625,7 +3694,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #endif #ifndef OPENSSL_NO_RSA - if ((alg_k & SSL_kRSA) && + if ((alg_k & (SSL_kRSA|SSL_kRSAPSK)) && // CJD: CHECKME: not 100% sure !(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL))) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT); @@ -3658,7 +3727,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP)) { #ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) + if (alg_k & (SSL_kRSA|SSL_kRSAPSK)) // CJD { if (rsa == NULL || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index d670ff0..7361b37 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -1715,6 +1715,73 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[]={ 256, 256, }, + +#ifndef OPENSSL_NO_RSA + /* RSA-PSK ciphersuites */ + /* 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 @@ -4522,7 +4589,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|SSL_kRSAPSK)) && s->psk_server_callback == NULL) continue; #endif /* OPENSSL_NO_PSK */ diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index bef055a..677db55 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -467,7 +467,8 @@ 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 + * 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 @@ -476,10 +477,8 @@ int ssl3_accept(SSL *s) * public key for key exchange. */ if (s->s3->tmp.use_rsa_tmp - /* 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|SSL_kRSAPSK)) && s->ctx->psk_identity_hint) #endif #ifndef OPENSSL_NO_SRP /* SRP: send ServerKeyExchange */ @@ -525,9 +524,9 @@ 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) - /* With normal PSK Certificates and + /* 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|SSL_kRSAPSK))) { /* no cert request */ skip=1; @@ -1894,7 +1893,17 @@ int ssl3_send_server_key_exchange(SSL *s) r[3]=s->srp_ctx.B; } else -#endif +#endif /*! OPENSSL_NO_SRP */ +#ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_PSK + if (type & SSL_kRSAPSK) + { + /* reserve size for record length and PSK identity hint */ + n+=2+strlen(s->ctx->psk_identity_hint); + } + else +#endif /* !OPENSSL_NO_PSK */ +#endif /* !OPENSSL_NO_RSA */ { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); @@ -1977,7 +1986,7 @@ int ssl3_send_server_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) + if (type & (SSL_kPSK|SSL_kRSAPSK)) { /* copy PSK identity hint */ s2n(strlen(s->ctx->psk_identity_hint), p); @@ -1992,7 +2001,7 @@ int ssl3_send_server_key_exchange(SSL *s) /* n is the length of the params, they start at &(d[4]) * and p 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) && !(type & SSL_kRSAPSK)) { q=md_buf; j=0; @@ -2878,8 +2887,195 @@ int ssl3_get_client_key_exchange(SSL *s) if (psk_err != 0) goto f_err; } - else + 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 /* !OPENSSL_NO_PSK */ +#endif /* !OPENSSL_NO_RSA */ #ifndef OPENSSL_NO_SRP if (alg_k & SSL_kSRP) { diff --git a/ssl/ssl.h b/ssl/ssl.h index 343247c..0f47f71 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -252,7 +252,8 @@ extern "C" { #define SSL_TXT_kECDH "kECDH" #define SSL_TXT_kEECDH "kEECDH" /* alias for kECDHE */ #define SSL_TXT_kECDHE "kECDHE" -#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_kRSAPSK "kRSAPSK" #define SSL_TXT_kGOST "kGOST" #define SSL_TXT_kSRP "kSRP" @@ -281,6 +282,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 a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 3c005f7..72f67f1 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -254,7 +254,8 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_kECDHE,0, SSL_kECDHE,0,0,0,0,0,0,0,0}, {0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kECDHE,0,0,0,0,0,0,0,0}, - {0,SSL_TXT_kPSK,0, SSL_kPSK, 0,0,0,0,0,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}, @@ -268,7 +269,7 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_aECDH,0, 0,SSL_aECDH, 0,0,0,0,0,0,0}, {0,SSL_TXT_aECDSA,0, 0,SSL_aECDSA,0,0,0,0,0,0,0}, {0,SSL_TXT_ECDSA,0, 0,SSL_aECDSA, 0,0,0,0,0,0,0}, - {0,SSL_TXT_aPSK,0, 0,SSL_aPSK, 0,0,0,0,0,0,0}, + {0,SSL_TXT_aPSK,0, 0,SSL_aPSK, 0,0,0,0,0,0,0}, {0,SSL_TXT_aGOST94,0,0,SSL_aGOST94,0,0,0,0,0,0,0}, {0,SSL_TXT_aGOST01,0,0,SSL_aGOST01,0,0,0,0,0,0,0}, {0,SSL_TXT_aGOST,0,0,SSL_aGOST94|SSL_aGOST01,0,0,0,0,0,0,0}, @@ -284,7 +285,8 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_RSA,0, SSL_kRSA,SSL_aRSA,0,0,0,0,0,0,0}, {0,SSL_TXT_ADH,0, SSL_kDHE,SSL_aNULL,0,0,0,0,0,0,0}, {0,SSL_TXT_AECDH,0, SSL_kECDHE,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_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}, @@ -755,7 +757,7 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un *auth |= SSL_aECDH; #endif #ifdef OPENSSL_NO_PSK - *mkey |= SSL_kPSK; + *mkey |= SSL_kPSK|SSL_kRSAPSK; *auth |= SSL_aPSK; #endif #ifdef OPENSSL_NO_SRP @@ -1535,7 +1537,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); /* ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); */ ssl_cipher_apply_rule(0, SSL_kRSA, 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_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, &tail); /* RC4 is sort-of broken -- move the the end */ @@ -1717,6 +1720,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kGOST: kx="GOST"; break; + case SSL_kRSAPSK: + kx="RSAPSK"; + break; default: kx="unknown"; } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 43204de..6969672 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2460,8 +2460,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 a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 1fd6bb1..2a5179b 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -301,6 +301,7 @@ #define SSL_kPSK 0x00000100L /* PSK */ #define SSL_kGOST 0x00000200L /* GOST key exchange */ #define SSL_kSRP 0x00000400L /* SRP */ +#define SSL_kRSAPSK 0x00000800L /* RSA-PSK */ /* Bits for algorithm_auth (server authentication) */ #define SSL_aRSA 0x00000001L /* RSA auth */ diff --git a/ssl/tls1.h b/ssl/tls1.h index e8188ec..c7b4606 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -416,6 +416,12 @@ 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 +/* 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 + /* Additional TLS ciphersuites from expired Internet Draft * draft-ietf-tls-56-bit-ciphersuites-01.txt * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see @@ -655,6 +661,12 @@ 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" +/* RSA-PSK ciphersuites from 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" + /* 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" -- 1.7.9.5
smime.p7s
Description: S/MIME cryptographic signature
