Add SRP.
This commit is contained in:
@@ -30,7 +30,7 @@ LIBSRC= \
|
||||
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
|
||||
ssl_ciph.c ssl_stat.c ssl_rsa.c \
|
||||
ssl_asn1.c ssl_txt.c ssl_algs.c \
|
||||
bio_ssl.c ssl_err.c kssl.c t1_reneg.c
|
||||
bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c
|
||||
LIBOBJ= \
|
||||
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
|
||||
s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \
|
||||
@@ -41,7 +41,7 @@ LIBOBJ= \
|
||||
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
|
||||
ssl_ciph.o ssl_stat.o ssl_rsa.o \
|
||||
ssl_asn1.o ssl_txt.o ssl_algs.o \
|
||||
bio_ssl.o ssl_err.o kssl.o t1_reneg.o
|
||||
bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
|
||||
138
ssl/s3_clnt.c
138
ssl/s3_clnt.c
@@ -277,6 +277,20 @@ int ssl3_connect(SSL *s)
|
||||
case SSL3_ST_CR_SRVR_HELLO_A:
|
||||
case SSL3_ST_CR_SRVR_HELLO_B:
|
||||
ret=ssl3_get_server_hello(s);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (ret == 0 && s->s3->warn_alert == SSL_AD_MISSING_SRP_USERNAME)
|
||||
{
|
||||
if (!SRP_have_to_put_srp_username(s))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_MISSING_SRP_USERNAME);
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_USER_CANCELLED);
|
||||
goto end;
|
||||
}
|
||||
s->state=SSL3_ST_CW_CLNT_HELLO_A;
|
||||
if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (ret <= 0) goto end;
|
||||
|
||||
if (s->hit)
|
||||
@@ -358,6 +372,17 @@ int ssl3_connect(SSL *s)
|
||||
case SSL3_ST_CR_SRVR_DONE_B:
|
||||
ret=ssl3_get_server_done(s);
|
||||
if (ret <= 0) goto end;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP)
|
||||
{
|
||||
if ((ret = SRP_Calc_A_param(s))<=0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_SRP_A_CALC);
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (s->s3->tmp.cert_req)
|
||||
s->state=SSL3_ST_CW_CERT_A;
|
||||
else
|
||||
@@ -1283,6 +1308,86 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
}
|
||||
else
|
||||
#endif /* !OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (alg_k & SSL_kSRP)
|
||||
{
|
||||
n2s(p,i);
|
||||
param_len=i+2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p+=i;
|
||||
|
||||
n2s(p,i);
|
||||
param_len+=i+2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p+=i;
|
||||
|
||||
i = (unsigned int)(p[0]);
|
||||
p++;
|
||||
param_len+=i+1;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p+=i;
|
||||
|
||||
n2s(p,i);
|
||||
param_len+=i+2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p+=i;
|
||||
n-=param_len;
|
||||
|
||||
/* We must check if there is a certificate */
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (alg_a & SSL_aRSA)
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
|
||||
#else
|
||||
if (0)
|
||||
;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
else if (alg_a & SSL_aDSS)
|
||||
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif /* !OPENSSL_NO_SRP */
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (alg_k & SSL_kRSA)
|
||||
{
|
||||
@@ -2552,6 +2657,39 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
EVP_PKEY_free(pub_key);
|
||||
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
else if (alg_k & SSL_kSRP)
|
||||
{
|
||||
if (s->srp_ctx.A != NULL)
|
||||
{
|
||||
/* send off the data */
|
||||
n=BN_num_bytes(s->srp_ctx.A);
|
||||
s2n(n,p);
|
||||
BN_bn2bin(s->srp_ctx.A,p);
|
||||
n+=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (s->session->srp_username != NULL)
|
||||
OPENSSL_free(s->session->srp_username);
|
||||
s->session->srp_username = BUF_strdup(s->srp_ctx.login);
|
||||
if (s->session->srp_username == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((s->session->master_key_length = SRP_generate_client_master_secret(s,s->session->master_key))<0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
else if (alg_k & SSL_kPSK)
|
||||
{
|
||||
|
||||
213
ssl/s3_lib.c
213
ssl/s3_lib.c
@@ -2012,6 +2012,152 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
|
||||
},
|
||||
#endif /* OPENSSL_NO_ECDH */
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* Cipher C01A */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aNULL,
|
||||
SSL_3DES,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
168,
|
||||
168,
|
||||
},
|
||||
|
||||
/* Cipher C01B */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aRSA,
|
||||
SSL_3DES,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
168,
|
||||
168,
|
||||
},
|
||||
|
||||
/* Cipher C01C */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aDSS,
|
||||
SSL_3DES,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
168,
|
||||
168,
|
||||
},
|
||||
|
||||
/* Cipher C01D */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aNULL,
|
||||
SSL_AES128,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
|
||||
/* Cipher C01E */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aRSA,
|
||||
SSL_AES128,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
|
||||
/* Cipher C01F */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aDSS,
|
||||
SSL_AES128,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
128,
|
||||
128,
|
||||
},
|
||||
|
||||
/* Cipher C020 */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aNULL,
|
||||
SSL_AES256,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
|
||||
/* Cipher C021 */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aRSA,
|
||||
SSL_AES256,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
|
||||
/* Cipher C022 */
|
||||
{
|
||||
1,
|
||||
TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
|
||||
TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
|
||||
SSL_kSRP,
|
||||
SSL_aDSS,
|
||||
SSL_AES256,
|
||||
SSL_SHA1,
|
||||
SSL_TLSV1,
|
||||
SSL_NOT_EXP|SSL_HIGH,
|
||||
SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
|
||||
256,
|
||||
256,
|
||||
},
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
|
||||
#ifdef TEMP_GOST_TLS
|
||||
/* Cipher FF00 */
|
||||
{
|
||||
@@ -2128,6 +2274,9 @@ int ssl3_new(SSL *s)
|
||||
|
||||
s->s3=s3;
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SSL_SRP_CTX_init(s);
|
||||
#endif
|
||||
s->method->ssl_clear(s);
|
||||
return(1);
|
||||
err:
|
||||
@@ -2168,6 +2317,9 @@ void ssl3_free(SSL *s)
|
||||
BIO_free(s->s3->handshake_buffer);
|
||||
}
|
||||
if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SSL_SRP_CTX_free(s);
|
||||
#endif
|
||||
OPENSSL_cleanse(s->s3,sizeof *s->s3);
|
||||
OPENSSL_free(s->s3);
|
||||
s->s3=NULL;
|
||||
@@ -2232,6 +2384,13 @@ void ssl3_clear(SSL *s)
|
||||
s->version=SSL3_VERSION;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
static char * MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg)
|
||||
{
|
||||
return BUF_strdup(s->srp_ctx.info) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
{
|
||||
int ret=0;
|
||||
@@ -2709,6 +2868,38 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
if (ctx->srp_ctx.login != NULL)
|
||||
OPENSSL_free(ctx->srp_ctx.login);
|
||||
ctx->srp_ctx.login = NULL;
|
||||
if (parg == NULL)
|
||||
break;
|
||||
if (strlen((char *)parg) > 254)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME);
|
||||
return 0;
|
||||
}
|
||||
if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD:
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback=srp_password_from_info_cb;
|
||||
ctx->srp_ctx.info=parg;
|
||||
break;
|
||||
case SSL_CTRL_SET_SRP_ARG:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.SRP_cb_arg=parg;
|
||||
break;
|
||||
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH:
|
||||
ctx->srp_ctx.strength=larg;
|
||||
break;
|
||||
#endif
|
||||
#endif /* !OPENSSL_NO_TLSEXT */
|
||||
|
||||
/* A Thawte special :-) */
|
||||
@@ -2778,6 +2969,24 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
|
||||
HMAC_CTX *, int))fp;
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.SRP_verify_param_callback=(int (*)(SSL *,void *))fp;
|
||||
break;
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.TLS_ext_srp_username_callback=(int (*)(SSL *,int *,void *))fp;
|
||||
break;
|
||||
case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
|
||||
break;
|
||||
case SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB:
|
||||
ctx->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback=(char *(*)(SSL *,void *))fp;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
return(0);
|
||||
@@ -2878,6 +3087,10 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
mask_a = cert->mask_a;
|
||||
emask_k = cert->export_mask_k;
|
||||
emask_a = cert->export_mask_a;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
mask_k=cert->mask_k | s->srp_ctx.srp_Mask;
|
||||
emask_k=cert->export_mask_k | s->srp_ctx.srp_Mask;
|
||||
#endif
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
/* printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
|
||||
|
||||
@@ -1203,6 +1203,10 @@ start:
|
||||
SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
|
||||
goto f_err;
|
||||
}
|
||||
#ifdef SSL_AD_MISSING_SRP_USERNAME
|
||||
if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
else if (alert_level == 2) /* fatal */
|
||||
{
|
||||
|
||||
140
ssl/s3_srvr.c
140
ssl/s3_srvr.c
@@ -179,6 +179,31 @@ static const SSL_METHOD *ssl3_get_server_method(int ver)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
static int SSL_check_srp_ext_ClientHello(SSL *s, int *ad)
|
||||
{
|
||||
int ret = SSL_ERROR_NONE;
|
||||
|
||||
*ad = SSL_AD_UNRECOGNIZED_NAME;
|
||||
|
||||
if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
|
||||
(s->srp_ctx.TLS_ext_srp_username_callback != NULL))
|
||||
{
|
||||
if(s->srp_ctx.login == NULL)
|
||||
{
|
||||
/* There isn't any srp login extension !!! */
|
||||
ret = SSL3_AL_WARNING;
|
||||
*ad = SSL_AD_MISSING_SRP_USERNAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SSL_srp_server_param_with_username(s,ad);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
|
||||
ssl3_accept,
|
||||
ssl_undefined_function,
|
||||
@@ -191,6 +216,10 @@ int ssl3_accept(SSL *s)
|
||||
void (*cb)(const SSL *ssl,int type,int val)=NULL;
|
||||
int ret= -1;
|
||||
int new_state,state,skip=0;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
int srp_no_username=0;
|
||||
int extension_error,al;
|
||||
#endif
|
||||
|
||||
RAND_add(&Time,sizeof(Time),0);
|
||||
ERR_clear_error();
|
||||
@@ -311,10 +340,34 @@ int ssl3_accept(SSL *s)
|
||||
case SSL3_ST_SR_CLNT_HELLO_A:
|
||||
case SSL3_ST_SR_CLNT_HELLO_B:
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME:
|
||||
#endif
|
||||
|
||||
s->shutdown=0;
|
||||
ret=ssl3_get_client_hello(s);
|
||||
if (ret <= 0) goto end;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
extension_error = 0;
|
||||
if ((al = SSL_check_srp_ext_ClientHello(s,&extension_error)) != SSL_ERROR_NONE)
|
||||
{
|
||||
ssl3_send_alert(s,al,extension_error);
|
||||
if (extension_error == SSL_AD_MISSING_SRP_USERNAME)
|
||||
{
|
||||
if (srp_no_username) goto end;
|
||||
ERR_clear_error();
|
||||
srp_no_username = 1;
|
||||
s->state=SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME;
|
||||
if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
|
||||
if ((ret=BIO_flush(s->wbio)) <= 0) goto end;
|
||||
s->init_num=0;
|
||||
break;
|
||||
}
|
||||
ret = -1;
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
s->renegotiate = 2;
|
||||
s->state=SSL3_ST_SW_SRVR_HELLO_A;
|
||||
@@ -345,7 +398,7 @@ int ssl3_accept(SSL *s)
|
||||
case SSL3_ST_SW_CERT_A:
|
||||
case SSL3_ST_SW_CERT_B:
|
||||
/* Check if it is anon DH or anon ECDH, */
|
||||
/* normal PSK or KRB5 */
|
||||
/* normal PSK or KRB5 or SRP */
|
||||
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
|
||||
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
|
||||
&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
|
||||
@@ -409,6 +462,10 @@ int ssl3_accept(SSL *s)
|
||||
* hint if provided */
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
|| ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* SRP: send ServerKeyExchange */
|
||||
|| (alg_k & SSL_kSRP)
|
||||
#endif
|
||||
|| (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
|
||||
|| (alg_k & SSL_kEECDH)
|
||||
@@ -803,7 +860,11 @@ int ssl3_get_client_hello(SSL *s)
|
||||
* If we are SSLv3, we will respond with SSLv3, even if prompted with
|
||||
* TLSv1.
|
||||
*/
|
||||
if (s->state == SSL3_ST_SR_CLNT_HELLO_A)
|
||||
if (s->state == SSL3_ST_SR_CLNT_HELLO_A
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
|| (s->state == SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
s->state=SSL3_ST_SR_CLNT_HELLO_B;
|
||||
}
|
||||
@@ -1668,14 +1729,37 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
}
|
||||
else
|
||||
#endif /* !OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (type & SSL_kSRP)
|
||||
{
|
||||
if ((s->srp_ctx.N == NULL) ||
|
||||
(s->srp_ctx.g == NULL) ||
|
||||
(s->srp_ctx.s == NULL) ||
|
||||
(s->srp_ctx.B == NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_SRP_PARAM);
|
||||
goto err;
|
||||
}
|
||||
r[0]=s->srp_ctx.N;
|
||||
r[1]=s->srp_ctx.g;
|
||||
r[2]=s->srp_ctx.s;
|
||||
r[3]=s->srp_ctx.B;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
|
||||
goto f_err;
|
||||
}
|
||||
for (i=0; r[i] != NULL; i++)
|
||||
for (i=0; r[i] != NULL && i<4; i++)
|
||||
{
|
||||
nr[i]=BN_num_bytes(r[i]);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if ((i == 2) && (type & SSL_kSRP))
|
||||
n+=1+nr[i];
|
||||
else
|
||||
#endif
|
||||
n+=2+nr[i];
|
||||
}
|
||||
|
||||
@@ -1704,8 +1788,16 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
d=(unsigned char *)s->init_buf->data;
|
||||
p= &(d[4]);
|
||||
|
||||
for (i=0; r[i] != NULL; i++)
|
||||
for (i=0; r[i] != NULL && i<4; i++)
|
||||
{
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if ((i == 2) && (type & SSL_kSRP))
|
||||
{
|
||||
*p = nr[i];
|
||||
p++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
s2n(nr[i],p);
|
||||
BN_bn2bin(r[i],p);
|
||||
p+=nr[i];
|
||||
@@ -2581,6 +2673,44 @@ int ssl3_get_client_key_exchange(SSL *s)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (alg_k & SSL_kSRP)
|
||||
{
|
||||
int param_len;
|
||||
|
||||
n2s(p,i);
|
||||
param_len=i+2;
|
||||
if (param_len > n)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (s->session->srp_username != NULL)
|
||||
OPENSSL_free(s->session->srp_username);
|
||||
s->session->srp_username = BUF_strdup(s->srp_ctx.login);
|
||||
if (s->session->srp_username == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
p+=i;
|
||||
}
|
||||
else
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
if (alg_k & SSL_kGOST)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -2664,7 +2794,7 @@ int ssl3_get_client_key_exchange(SSL *s)
|
||||
return(1);
|
||||
f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)
|
||||
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP)
|
||||
err:
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
|
||||
96
ssl/ssl.h
96
ssl/ssl.h
@@ -252,6 +252,7 @@ extern "C" {
|
||||
#define SSL_TXT_kEECDH "kEECDH"
|
||||
#define SSL_TXT_kPSK "kPSK"
|
||||
#define SSL_TXT_kGOST "kGOST"
|
||||
#define SSL_TXT_kSRP "kSRP"
|
||||
|
||||
#define SSL_TXT_aRSA "aRSA"
|
||||
#define SSL_TXT_aDSS "aDSS"
|
||||
@@ -275,6 +276,7 @@ extern "C" {
|
||||
#define SSL_TXT_ECDSA "ECDSA"
|
||||
#define SSL_TXT_KRB5 "KRB5"
|
||||
#define SSL_TXT_PSK "PSK"
|
||||
#define SSL_TXT_SRP "SRP"
|
||||
|
||||
#define SSL_TXT_DES "DES"
|
||||
#define SSL_TXT_3DES "3DES"
|
||||
@@ -437,6 +439,7 @@ typedef struct ssl_method_st
|
||||
* ECPointFormatList [ 7 ] OCTET STRING, -- optional EC point format list from TLS extension
|
||||
* PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
|
||||
* PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity
|
||||
* SRP_username [ 11 ] EXPLICIT OCTET STRING -- optional SRP username
|
||||
* }
|
||||
* Look in ssl/ssl_asn1.c for more details
|
||||
* I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
|
||||
@@ -512,6 +515,9 @@ typedef struct ssl_session_st
|
||||
unsigned char *tlsext_tick; /* Session ticket */
|
||||
size_t tlsext_ticklen; /* Session ticket length */
|
||||
long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
char *srp_username;
|
||||
#endif
|
||||
} SSL_SESSION;
|
||||
|
||||
@@ -644,7 +650,42 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
|
||||
#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
|
||||
#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
|
||||
typedef struct srp_ctx_st
|
||||
{
|
||||
/* param for all the callbacks */
|
||||
void *SRP_cb_arg;
|
||||
/* set client Hello login callback */
|
||||
int (*TLS_ext_srp_username_callback)(SSL *, int *, void *);
|
||||
/* set SRP N/g param callback for verification */
|
||||
int (*SRP_verify_param_callback)(SSL *, void *);
|
||||
/* set SRP client passwd callback */
|
||||
char *(*SRP_give_srp_client_pwd_callback)(SSL *, void *);
|
||||
/* set SRP client username callback */
|
||||
char *(*SRP_TLS_ext_missing_srp_client_username_callback)(SSL *, void *);
|
||||
|
||||
char *login;
|
||||
BIGNUM *N,*g,*s,*B,*A;
|
||||
BIGNUM *a,*b,*v;
|
||||
char *info;
|
||||
int strength;
|
||||
|
||||
unsigned long srp_Mask;
|
||||
} SRP_CTX;
|
||||
|
||||
/* see tls_srp.c */
|
||||
int SSL_SRP_CTX_init(SSL *s);
|
||||
int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
|
||||
int SSL_SRP_CTX_free(SSL *ctx);
|
||||
int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
|
||||
int SSL_srp_server_param_with_username(SSL *s, int *ad);
|
||||
int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key);
|
||||
int SRP_Calc_A_param(SSL *s);
|
||||
int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key);
|
||||
int SRP_have_to_put_srp_username(SSL *s);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
|
||||
#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
|
||||
@@ -868,6 +909,9 @@ struct ssl_ctx_st
|
||||
unsigned int freelist_max_len;
|
||||
struct ssl3_buf_freelist_st *wbuf_freelist;
|
||||
struct ssl3_buf_freelist_st *rbuf_freelist;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SRP_CTX srp_ctx; /* ctx for SRP authentication */
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1112,6 +1156,10 @@ struct ssl_st
|
||||
unsigned char *psk, unsigned int max_psk_len);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SRP_CTX srp_ctx; /* ctx for SRP authentication */
|
||||
#endif
|
||||
|
||||
SSL_CTX *ctx;
|
||||
/* set this flag to 1 and a sleep(1) is put into all SSL_read()
|
||||
* and SSL_write() calls, good for nbio debuging :-) */
|
||||
@@ -1329,6 +1377,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
|
||||
#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
|
||||
#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
|
||||
#define SSL_AD_UNKNOWN_SRP_USERNAME TLS1_AD_UNKNOWN_SRP_USERNAME
|
||||
#define SSL_AD_MISSING_SRP_USERNAME TLS1_AD_MISSING_SRP_USERNAME
|
||||
|
||||
#define SSL_ERROR_NONE 0
|
||||
#define SSL_ERROR_SSL 1
|
||||
@@ -1412,6 +1462,15 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71
|
||||
|
||||
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
|
||||
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75
|
||||
#define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76
|
||||
#define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB 78
|
||||
#define SSL_CTRL_SET_SRP_ARG 79
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 80
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 81
|
||||
#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 82
|
||||
#endif
|
||||
|
||||
#define DTLS_CTRL_GET_TIMEOUT 73
|
||||
@@ -1616,6 +1675,32 @@ int SSL_set_trust(SSL *s, int trust);
|
||||
int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
|
||||
int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name);
|
||||
int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password);
|
||||
int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
|
||||
int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
|
||||
char *(*cb)(SSL *,void *));
|
||||
int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
|
||||
int (*cb)(SSL *,void *));
|
||||
int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
|
||||
int (*cb)(SSL *,int *,void *));
|
||||
int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx,
|
||||
char *(*cb)(SSL *,void *));
|
||||
int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);
|
||||
|
||||
int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
|
||||
BIGNUM *sa, BIGNUM *v, char *info);
|
||||
int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
|
||||
const char *grp);
|
||||
|
||||
BIGNUM *SSL_get_srp_g(SSL *s);
|
||||
BIGNUM *SSL_get_srp_N(SSL *s);
|
||||
|
||||
char *SSL_get_srp_username(SSL *s);
|
||||
char *SSL_get_srp_userinfo(SSL *s);
|
||||
#endif
|
||||
|
||||
void SSL_free(SSL *ssl);
|
||||
int SSL_accept(SSL *ssl);
|
||||
int SSL_connect(SSL *ssl);
|
||||
@@ -2008,6 +2093,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_SET_TRUST 228
|
||||
#define SSL_F_SSL_SET_WFD 196
|
||||
#define SSL_F_SSL_SHUTDOWN 224
|
||||
#define SSL_F_SSL_SRP_CTX_INIT 293
|
||||
#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243
|
||||
#define SSL_F_SSL_UNDEFINED_FUNCTION 197
|
||||
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
|
||||
@@ -2066,6 +2152,11 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_BAD_RSA_MODULUS_LENGTH 121
|
||||
#define SSL_R_BAD_RSA_SIGNATURE 122
|
||||
#define SSL_R_BAD_SIGNATURE 123
|
||||
#define SSL_R_BAD_SRP_A_LENGTH 2096
|
||||
#define SSL_R_BAD_SRP_B_LENGTH 2097
|
||||
#define SSL_R_BAD_SRP_G_LENGTH 2098
|
||||
#define SSL_R_BAD_SRP_N_LENGTH 2099
|
||||
#define SSL_R_BAD_SRP_S_LENGTH 2100
|
||||
#define SSL_R_BAD_SSL_FILETYPE 124
|
||||
#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125
|
||||
#define SSL_R_BAD_STATE 126
|
||||
@@ -2082,6 +2173,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137
|
||||
#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138
|
||||
#define SSL_R_CIPHER_TABLE_SRC_ERROR 139
|
||||
#define SSL_R_CLIENTHELLO_SRP_TLS_EXT 2101
|
||||
#define SSL_R_CLIENTHELLO_TLSEXT 226
|
||||
#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140
|
||||
#define SSL_R_COMPRESSION_DISABLED 343
|
||||
@@ -2118,6 +2210,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_INVALID_COMMAND 280
|
||||
#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
|
||||
#define SSL_R_INVALID_PURPOSE 278
|
||||
#define SSL_R_INVALID_SRP_USERNAME 2107
|
||||
#define SSL_R_INVALID_STATUS_RESPONSE 328
|
||||
#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325
|
||||
#define SSL_R_INVALID_TRUST 279
|
||||
@@ -2147,6 +2240,8 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_MISSING_RSA_CERTIFICATE 168
|
||||
#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169
|
||||
#define SSL_R_MISSING_RSA_SIGNING_CERT 170
|
||||
#define SSL_R_MISSING_SRP_PARAM 2103
|
||||
#define SSL_R_MISSING_SRP_USERNAME 2104
|
||||
#define SSL_R_MISSING_TMP_DH_KEY 171
|
||||
#define SSL_R_MISSING_TMP_ECDH_KEY 311
|
||||
#define SSL_R_MISSING_TMP_RSA_KEY 172
|
||||
@@ -2219,6 +2314,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
|
||||
#define SSL_R_SHORT_READ 219
|
||||
#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
|
||||
#define SSL_R_SRP_A_CALC 2105
|
||||
#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221
|
||||
#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299
|
||||
#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321
|
||||
|
||||
@@ -566,6 +566,8 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
|
||||
/* a new state to remember that we have already receive a ClientHello without srp username extension */
|
||||
#define SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME (0x1E2|SSL_ST_ACCEPT)
|
||||
/* write to client */
|
||||
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
|
||||
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
|
||||
|
||||
@@ -114,6 +114,9 @@ typedef struct ssl_session_asn1_st
|
||||
ASN1_OCTET_STRING psk_identity_hint;
|
||||
ASN1_OCTET_STRING psk_identity;
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
ASN1_OCTET_STRING srp_username;
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
} SSL_SESSION_ASN1;
|
||||
|
||||
int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
@@ -129,6 +132,9 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
unsigned char cbuf;
|
||||
int v11=0;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
int v12=0;
|
||||
#endif
|
||||
long l;
|
||||
SSL_SESSION_ASN1 a;
|
||||
@@ -267,6 +273,14 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
a.psk_identity.data=(unsigned char *)(in->psk_identity);
|
||||
}
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (in->srp_username)
|
||||
{
|
||||
a.srp_username.length=strlen(in->srp_username);
|
||||
a.srp_username.type=V_ASN1_OCTET_STRING;
|
||||
a.srp_username.data=(unsigned char *)(in->srp_username);
|
||||
}
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
|
||||
M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER);
|
||||
M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER);
|
||||
@@ -307,6 +321,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
if (in->psk_identity)
|
||||
M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
|
||||
#endif /* OPENSSL_NO_PSK */
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (in->srp_username)
|
||||
M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
|
||||
M_ASN1_I2D_seq_total();
|
||||
|
||||
@@ -351,6 +369,10 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
|
||||
if (in->compress_meth)
|
||||
M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (in->srp_username)
|
||||
M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
M_ASN1_I2D_finish();
|
||||
}
|
||||
|
||||
@@ -588,5 +610,20 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
os.length=0;
|
||||
os.data=NULL;
|
||||
M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11);
|
||||
if (os.data)
|
||||
{
|
||||
ret->srp_username = BUF_strndup((char *)os.data, os.length);
|
||||
OPENSSL_free(os.data);
|
||||
os.data = NULL;
|
||||
os.length = 0;
|
||||
}
|
||||
else
|
||||
ret->srp_username=NULL;
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
|
||||
M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
|
||||
}
|
||||
|
||||
@@ -247,6 +247,7 @@ static const SSL_CIPHER cipher_aliases[]={
|
||||
{0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,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_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},
|
||||
|
||||
/* server authentication aliases */
|
||||
@@ -273,6 +274,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_SRP,0, SSL_kSRP,0,0,0,0,0,0,0,0},
|
||||
|
||||
|
||||
/* symmetric encryption aliases */
|
||||
@@ -660,6 +662,9 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un
|
||||
#ifdef OPENSSL_NO_PSK
|
||||
*mkey |= SSL_kPSK;
|
||||
*auth |= SSL_aPSK;
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_SRP
|
||||
*mkey |= SSL_kSRP;
|
||||
#endif
|
||||
/* Check for presence of GOST 34.10 algorithms, and if they
|
||||
* do not present, disable appropriate auth and key exchange */
|
||||
@@ -1511,6 +1516,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
|
||||
case SSL_kPSK:
|
||||
kx="PSK";
|
||||
break;
|
||||
case SSL_kSRP:
|
||||
kx="SRP";
|
||||
break;
|
||||
default:
|
||||
kx="unknown";
|
||||
}
|
||||
|
||||
@@ -250,6 +250,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"},
|
||||
{ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"},
|
||||
{ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"},
|
||||
{ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_INIT"},
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "SSL_UNDEFINED_CONST_FUNCTION"},
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "SSL_UNDEFINED_FUNCTION"},
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "SSL_UNDEFINED_VOID_FUNCTION"},
|
||||
@@ -311,6 +312,11 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH),"bad rsa modulus length"},
|
||||
{ERR_REASON(SSL_R_BAD_RSA_SIGNATURE) ,"bad rsa signature"},
|
||||
{ERR_REASON(SSL_R_BAD_SIGNATURE) ,"bad signature"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_A_LENGTH) ,"bad srp a length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_B_LENGTH) ,"bad srp b length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_G_LENGTH) ,"bad srp g length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_N_LENGTH) ,"bad srp n length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_S_LENGTH) ,"bad srp s length"},
|
||||
{ERR_REASON(SSL_R_BAD_SSL_FILETYPE) ,"bad ssl filetype"},
|
||||
{ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"},
|
||||
{ERR_REASON(SSL_R_BAD_STATE) ,"bad state"},
|
||||
@@ -327,6 +333,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
|
||||
{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
|
||||
{ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
|
||||
{ERR_REASON(SSL_R_CLIENTHELLO_SRP_TLS_EXT),"error with the SRP username"},
|
||||
{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) ,"clienthello tlsext"},
|
||||
{ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),"compressed length too long"},
|
||||
{ERR_REASON(SSL_R_COMPRESSION_DISABLED) ,"compression disabled"},
|
||||
@@ -363,6 +370,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
|
||||
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
|
||||
{ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"},
|
||||
{ERR_REASON(SSL_R_INVALID_SRP_USERNAME) ,"invalid srp username"},
|
||||
{ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
|
||||
{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"},
|
||||
{ERR_REASON(SSL_R_INVALID_TRUST) ,"invalid trust"},
|
||||
@@ -392,6 +400,8 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE),"missing rsa certificate"},
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),"missing rsa encrypting cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT),"missing rsa signing cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_SRP_PARAM) ,"can't find SRP server param"},
|
||||
{ERR_REASON(SSL_R_MISSING_SRP_USERNAME) ,"missing srp username"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_DH_KEY) ,"missing tmp dh key"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY) ,"missing tmp ecdh key"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) ,"missing tmp rsa key"},
|
||||
@@ -464,6 +474,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
|
||||
{ERR_REASON(SSL_R_SHORT_READ) ,"short read"},
|
||||
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
|
||||
{ERR_REASON(SSL_R_SRP_A_CALC) ,"error with the srp params"},
|
||||
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
|
||||
{ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),"ssl2 connection id too long"},
|
||||
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),"ssl3 ext invalid ecpointformat"},
|
||||
|
||||
@@ -1657,6 +1657,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
ret->psk_client_callback=NULL;
|
||||
ret->psk_server_callback=NULL;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SSL_CTX_SRP_CTX_init(ret);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_BUF_FREELISTS
|
||||
ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
|
||||
ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
|
||||
@@ -1789,6 +1792,9 @@ void SSL_CTX_free(SSL_CTX *a)
|
||||
if (a->psk_identity_hint)
|
||||
OPENSSL_free(a->psk_identity_hint);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
SSL_CTX_SRP_CTX_free(a);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (a->client_cert_engine)
|
||||
ENGINE_finish(a->client_cert_engine);
|
||||
|
||||
@@ -289,6 +289,7 @@
|
||||
#define SSL_kEECDH 0x00000080L /* ephemeral ECDH */
|
||||
#define SSL_kPSK 0x00000100L /* PSK */
|
||||
#define SSL_kGOST 0x00000200L /* GOST key exchange */
|
||||
#define SSL_kSRP 0x00000400L /* SRP */
|
||||
|
||||
/* Bits for algorithm_auth (server authentication) */
|
||||
#define SSL_aRSA 0x00000001L /* RSA auth */
|
||||
|
||||
@@ -217,6 +217,9 @@ SSL_SESSION *SSL_SESSION_new(void)
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
ss->psk_identity_hint=NULL;
|
||||
ss->psk_identity=NULL;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
ss->srp_username=NULL;
|
||||
#endif
|
||||
return(ss);
|
||||
}
|
||||
@@ -733,6 +736,10 @@ void SSL_SESSION_free(SSL_SESSION *ss)
|
||||
OPENSSL_free(ss->psk_identity_hint);
|
||||
if (ss->psk_identity != NULL)
|
||||
OPENSSL_free(ss->psk_identity);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (ss->srp_username != NULL)
|
||||
OPENSSL_free(ss->srp_username);
|
||||
#endif
|
||||
OPENSSL_cleanse(ss,sizeof(*ss));
|
||||
OPENSSL_free(ss);
|
||||
|
||||
@@ -210,6 +210,9 @@ case SSL3_ST_SR_KEY_EXCH_A: str="SSLv3 read client key exchange A"; break;
|
||||
case SSL3_ST_SR_KEY_EXCH_B: str="SSLv3 read client key exchange B"; break;
|
||||
case SSL3_ST_SR_CERT_VRFY_A: str="SSLv3 read certificate verify A"; break;
|
||||
case SSL3_ST_SR_CERT_VRFY_B: str="SSLv3 read certificate verify B"; break;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME: str="SSLv3 waiting for a SRP username"; break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
||||
@@ -547,6 +550,11 @@ const char *SSL_alert_desc_string_long(int value)
|
||||
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
|
||||
str="unknown PSK identity";
|
||||
break;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case TLS1_AD_MISSING_SRP_USERNAME:
|
||||
str="no srp username";
|
||||
break;
|
||||
#endif
|
||||
default: str="unknown"; break;
|
||||
}
|
||||
return(str);
|
||||
|
||||
@@ -189,6 +189,10 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
|
||||
if (BIO_puts(bp,"\n PSK identity hint: ") <= 0) goto err;
|
||||
if (BIO_printf(bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) goto err;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (BIO_puts(bp,"\n SRP username: ") <= 0) goto err;
|
||||
if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) goto err;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (x->tlsext_tick_lifetime_hint)
|
||||
{
|
||||
|
||||
@@ -181,6 +181,9 @@
|
||||
#ifndef OPENSSL_NO_DH
|
||||
#include <openssl/dh.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#include <openssl/srp.h>
|
||||
#endif
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly
|
||||
@@ -246,6 +249,55 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned
|
||||
unsigned int max_psk_len);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* SRP client */
|
||||
/* This is a context that we pass to all callbacks */
|
||||
typedef struct srp_client_arg_st
|
||||
{
|
||||
char *srppassin;
|
||||
char *srplogin;
|
||||
} SRP_CLIENT_ARG;
|
||||
|
||||
#define PWD_STRLEN 1024
|
||||
|
||||
static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
|
||||
{
|
||||
SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
|
||||
return BUF_strdup((char *)srp_client_arg->srppassin);
|
||||
}
|
||||
|
||||
static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg)
|
||||
{
|
||||
SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
|
||||
return BUF_strdup(srp_client_arg->srplogin);
|
||||
}
|
||||
|
||||
/* SRP server */
|
||||
/* This is a context that we pass to SRP server callbacks */
|
||||
typedef struct srp_server_arg_st
|
||||
{
|
||||
char *expected_user;
|
||||
char *pass;
|
||||
} SRP_SERVER_ARG;
|
||||
|
||||
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
|
||||
{
|
||||
SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg;
|
||||
|
||||
if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0)
|
||||
{
|
||||
fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s));
|
||||
return SSL3_AL_FATAL;
|
||||
}
|
||||
if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0)
|
||||
{
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
return SSL3_AL_FATAL;
|
||||
}
|
||||
return SSL_ERROR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BIO *bio_err=NULL;
|
||||
static BIO *bio_stdout=NULL;
|
||||
|
||||
@@ -289,6 +341,10 @@ static void sv_usage(void)
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
fprintf(stderr," -psk arg - PSK in hex (without 0x)\n");
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
fprintf(stderr," -srpuser user - SRP username to use\n");
|
||||
fprintf(stderr," -srppass arg - password for 'user'\n");
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SSL2
|
||||
fprintf(stderr," -ssl2 - use SSLv2\n");
|
||||
#endif
|
||||
@@ -475,6 +531,13 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
EC_KEY *ecdh = NULL;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
/* client */
|
||||
int srp_lateuser = 0;
|
||||
SRP_CLIENT_ARG srp_client_arg = {NULL,NULL};
|
||||
/* server */
|
||||
SRP_SERVER_ARG srp_server_arg = {NULL,NULL};
|
||||
#endif
|
||||
int no_dhe = 0;
|
||||
int no_ecdhe = 0;
|
||||
@@ -572,6 +635,20 @@ int main(int argc, char *argv[])
|
||||
no_psk=1;
|
||||
#endif
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
else if (strcmp(*argv,"-srpuser") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv);
|
||||
tls1=1;
|
||||
}
|
||||
else if (strcmp(*argv,"-srppass") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
srp_server_arg.pass = srp_client_arg.srppassin= *(++argv);
|
||||
tls1=1;
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(*argv,"-ssl2") == 0)
|
||||
ssl2=1;
|
||||
else if (strcmp(*argv,"-tls1") == 0)
|
||||
@@ -940,6 +1017,28 @@ bad:
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (srp_client_arg.srplogin)
|
||||
{
|
||||
if (srp_lateuser)
|
||||
SSL_CTX_set_srp_missing_srp_username_callback(c_ctx,missing_srp_username_callback);
|
||||
else if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin))
|
||||
{
|
||||
BIO_printf(bio_err,"Unable to set SRP username\n");
|
||||
goto end;
|
||||
}
|
||||
SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg);
|
||||
SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb);
|
||||
/*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/
|
||||
}
|
||||
|
||||
if (srp_server_arg.expected_user != NULL)
|
||||
{
|
||||
SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback);
|
||||
SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg);
|
||||
SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
|
||||
}
|
||||
#endif
|
||||
|
||||
c_ssl=SSL_new(c_ctx);
|
||||
s_ssl=SSL_new(s_ctx);
|
||||
|
||||
@@ -1073,6 +1073,9 @@ int tls1_alert_code(int code)
|
||||
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
|
||||
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
|
||||
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
case SSL_AD_MISSING_SRP_USERNAME:return(TLS1_AD_MISSING_SRP_USERNAME);
|
||||
#endif
|
||||
#if 0 /* not appropriate for TLS, not used for DTLS */
|
||||
case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
|
||||
(DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
|
||||
|
||||
37
ssl/t1_lib.c
37
ssl/t1_lib.c
@@ -341,6 +341,30 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
ret += el;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||
/* we add SRP username the first time only if we have one! */
|
||||
if (s->srp_ctx.login != NULL)
|
||||
{/* Add TLS extension SRP username to the Client Hello message */
|
||||
int login_len = MIN(strlen(s->srp_ctx.login) + 1, 255);
|
||||
long lenmax;
|
||||
|
||||
if ((lenmax = limit - ret - 5) < 0) return NULL;
|
||||
if (login_len > lenmax) return NULL;
|
||||
if (login_len > 255)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
s2n(TLSEXT_TYPE_srp,ret);
|
||||
s2n(login_len+1,ret);
|
||||
|
||||
(*ret++) = (unsigned char) MIN(strlen(s->srp_ctx.login), 254);
|
||||
memcpy(ret, s->srp_ctx.login, MIN(strlen(s->srp_ctx.login), 254));
|
||||
ret+=login_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
if (s->tlsext_ecpointformatlist != NULL &&
|
||||
s->version != DTLS1_VERSION)
|
||||
@@ -762,6 +786,19 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
||||
}
|
||||
|
||||
}
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
else if (type == TLSEXT_TYPE_srp)
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
len = data[0];
|
||||
if ((s->srp_ctx.login = OPENSSL_malloc(len+1)) == NULL)
|
||||
return -1;
|
||||
memcpy(s->srp_ctx.login, &data[1], len);
|
||||
s->srp_ctx.login[len]='\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
else if (type == TLSEXT_TYPE_ec_point_formats &&
|
||||
|
||||
26
ssl/tls1.h
26
ssl/tls1.h
@@ -186,6 +186,8 @@ extern "C" {
|
||||
#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
|
||||
#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
|
||||
#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */
|
||||
#define TLS1_AD_UNKNOWN_SRP_USERNAME 120 /* fatal */
|
||||
#define TLS1_AD_MISSING_SRP_USERNAME 121
|
||||
|
||||
/* ExtensionType values from RFC3546 / RFC4366 */
|
||||
#define TLSEXT_TYPE_server_name 0
|
||||
@@ -197,6 +199,8 @@ extern "C" {
|
||||
/* ExtensionType values from RFC4492 */
|
||||
#define TLSEXT_TYPE_elliptic_curves 10
|
||||
#define TLSEXT_TYPE_ec_point_formats 11
|
||||
/* ExtensionType value from RFC5054 */
|
||||
#define TLSEXT_TYPE_srp 12
|
||||
#define TLSEXT_TYPE_session_ticket 35
|
||||
/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
|
||||
#if 0 /* will have to be provided externally for now ,
|
||||
@@ -380,6 +384,17 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
|
||||
#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018
|
||||
#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019
|
||||
|
||||
/* SRP ciphersuites from RFC 5054 */
|
||||
#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A
|
||||
#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B
|
||||
#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C
|
||||
#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D
|
||||
#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E
|
||||
#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F
|
||||
#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020
|
||||
#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021
|
||||
#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022
|
||||
|
||||
/* XXX
|
||||
* Inconsistency alert:
|
||||
* The OpenSSL names of ciphers with ephemeral DH here include the string
|
||||
@@ -447,6 +462,17 @@ 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"
|
||||
|
||||
/* 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"
|
||||
#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA"
|
||||
#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA"
|
||||
|
||||
/* Camellia ciphersuites from RFC4132 */
|
||||
#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA"
|
||||
#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA"
|
||||
|
||||
527
ssl/tls_srp.c
Normal file
527
ssl/tls_srp.c
Normal file
@@ -0,0 +1,527 @@
|
||||
/* ssl/tls_srp.c */
|
||||
/* Written by Christophe Renou (christophe.renou@edelweb.fr) with
|
||||
* the precious help of Peter Sylvester (peter.sylvester@edelweb.fr)
|
||||
* for the EdelKey project and contributed to the OpenSSL project 2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#include "ssl_locl.h"
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/srp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
OPENSSL_free(ctx->srp_ctx.login);
|
||||
BN_free(ctx->srp_ctx.N);
|
||||
BN_free(ctx->srp_ctx.g);
|
||||
BN_free(ctx->srp_ctx.s);
|
||||
BN_free(ctx->srp_ctx.B);
|
||||
BN_free(ctx->srp_ctx.A);
|
||||
BN_free(ctx->srp_ctx.a);
|
||||
BN_free(ctx->srp_ctx.b);
|
||||
BN_free(ctx->srp_ctx.v);
|
||||
ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
|
||||
ctx->srp_ctx.SRP_cb_arg = NULL;
|
||||
ctx->srp_ctx.SRP_verify_param_callback = NULL;
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
|
||||
ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
|
||||
ctx->srp_ctx.N = NULL;
|
||||
ctx->srp_ctx.g = NULL;
|
||||
ctx->srp_ctx.s = NULL;
|
||||
ctx->srp_ctx.B = NULL;
|
||||
ctx->srp_ctx.A = NULL;
|
||||
ctx->srp_ctx.a = NULL;
|
||||
ctx->srp_ctx.b = NULL;
|
||||
ctx->srp_ctx.v = NULL;
|
||||
ctx->srp_ctx.login = NULL;
|
||||
ctx->srp_ctx.info = NULL;
|
||||
ctx->srp_ctx.strength = SRP_MINIMAL_N;
|
||||
ctx->srp_ctx.srp_Mask = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int SSL_SRP_CTX_free(struct ssl_st *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
OPENSSL_free(s->srp_ctx.login);
|
||||
BN_free(s->srp_ctx.N);
|
||||
BN_free(s->srp_ctx.g);
|
||||
BN_free(s->srp_ctx.s);
|
||||
BN_free(s->srp_ctx.B);
|
||||
BN_free(s->srp_ctx.A);
|
||||
BN_free(s->srp_ctx.a);
|
||||
BN_free(s->srp_ctx.b);
|
||||
BN_free(s->srp_ctx.v);
|
||||
s->srp_ctx.TLS_ext_srp_username_callback = NULL;
|
||||
s->srp_ctx.SRP_cb_arg = NULL;
|
||||
s->srp_ctx.SRP_verify_param_callback = NULL;
|
||||
s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
|
||||
s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
|
||||
s->srp_ctx.N = NULL;
|
||||
s->srp_ctx.g = NULL;
|
||||
s->srp_ctx.s = NULL;
|
||||
s->srp_ctx.B = NULL;
|
||||
s->srp_ctx.A = NULL;
|
||||
s->srp_ctx.a = NULL;
|
||||
s->srp_ctx.b = NULL;
|
||||
s->srp_ctx.v = NULL;
|
||||
s->srp_ctx.login = NULL;
|
||||
s->srp_ctx.info = NULL;
|
||||
s->srp_ctx.strength = SRP_MINIMAL_N;
|
||||
s->srp_ctx.srp_Mask = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int SSL_SRP_CTX_init(struct ssl_st *s)
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
|
||||
if ((s == NULL) || ((ctx = s->ctx) == NULL))
|
||||
return 0;
|
||||
s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
|
||||
/* set client Hello login callback */
|
||||
s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback;
|
||||
/* set SRP N/g param callback for verification */
|
||||
s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback;
|
||||
/* set SRP client passwd callback */
|
||||
s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
|
||||
s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback;
|
||||
|
||||
s->srp_ctx.N = NULL;
|
||||
s->srp_ctx.g = NULL;
|
||||
s->srp_ctx.s = NULL;
|
||||
s->srp_ctx.B = NULL;
|
||||
s->srp_ctx.A = NULL;
|
||||
s->srp_ctx.a = NULL;
|
||||
s->srp_ctx.b = NULL;
|
||||
s->srp_ctx.v = NULL;
|
||||
s->srp_ctx.login = NULL;
|
||||
s->srp_ctx.info = ctx->srp_ctx.info;
|
||||
s->srp_ctx.strength = ctx->srp_ctx.strength;
|
||||
|
||||
if (((ctx->srp_ctx.N != NULL) &&
|
||||
((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
|
||||
((ctx->srp_ctx.g != NULL) &&
|
||||
((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
|
||||
((ctx->srp_ctx.s != NULL) &&
|
||||
((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
|
||||
((ctx->srp_ctx.B != NULL) &&
|
||||
((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
|
||||
((ctx->srp_ctx.A != NULL) &&
|
||||
((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
|
||||
((ctx->srp_ctx.a != NULL) &&
|
||||
((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
|
||||
((ctx->srp_ctx.v != NULL) &&
|
||||
((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
|
||||
((ctx->srp_ctx.b != NULL) &&
|
||||
((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if ((ctx->srp_ctx.login != NULL) &&
|
||||
((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
|
||||
|
||||
return (1);
|
||||
err:
|
||||
OPENSSL_free(s->srp_ctx.login);
|
||||
BN_free(s->srp_ctx.N);
|
||||
BN_free(s->srp_ctx.g);
|
||||
BN_free(s->srp_ctx.s);
|
||||
BN_free(s->srp_ctx.B);
|
||||
BN_free(s->srp_ctx.A);
|
||||
BN_free(s->srp_ctx.a);
|
||||
BN_free(s->srp_ctx.b);
|
||||
BN_free(s->srp_ctx.v);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
ctx->srp_ctx.SRP_cb_arg = NULL;
|
||||
/* set client Hello login callback */
|
||||
ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
|
||||
/* set SRP N/g param callback for verification */
|
||||
ctx->srp_ctx.SRP_verify_param_callback = NULL;
|
||||
/* set SRP client passwd callback */
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
|
||||
ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
|
||||
|
||||
ctx->srp_ctx.N = NULL;
|
||||
ctx->srp_ctx.g = NULL;
|
||||
ctx->srp_ctx.s = NULL;
|
||||
ctx->srp_ctx.B = NULL;
|
||||
ctx->srp_ctx.A = NULL;
|
||||
ctx->srp_ctx.a = NULL;
|
||||
ctx->srp_ctx.b = NULL;
|
||||
ctx->srp_ctx.v = NULL;
|
||||
ctx->srp_ctx.login = NULL;
|
||||
ctx->srp_ctx.srp_Mask = 0;
|
||||
ctx->srp_ctx.info = NULL;
|
||||
ctx->srp_ctx.strength = SRP_MINIMAL_N;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* server side */
|
||||
int SSL_srp_server_param_with_username(SSL *s, int *ad)
|
||||
{
|
||||
unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
int al;
|
||||
|
||||
*ad = SSL_AD_UNKNOWN_SRP_USERNAME;
|
||||
if ((s->srp_ctx.TLS_ext_srp_username_callback !=NULL) &&
|
||||
((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg))!=SSL_ERROR_NONE))
|
||||
return al;
|
||||
|
||||
*ad = SSL_AD_INTERNAL_ERROR;
|
||||
if ((s->srp_ctx.N == NULL) ||
|
||||
(s->srp_ctx.g == NULL) ||
|
||||
(s->srp_ctx.s == NULL) ||
|
||||
(s->srp_ctx.v == NULL))
|
||||
return SSL3_AL_FATAL;
|
||||
|
||||
RAND_bytes(b, sizeof(b));
|
||||
s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL);
|
||||
OPENSSL_cleanse(b,sizeof(b));
|
||||
|
||||
/* Calculate: B = (kv + g^b) % N */
|
||||
|
||||
return ((s->srp_ctx.B = SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, s->srp_ctx.v)) != NULL)?
|
||||
SSL_ERROR_NONE:SSL3_AL_FATAL;
|
||||
}
|
||||
|
||||
/* If the server just has the raw password, make up a verifier entry on the fly */
|
||||
int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp)
|
||||
{
|
||||
SRP_gN *GN = SRP_get_default_gN(grp);
|
||||
if(GN == NULL) return -1;
|
||||
s->srp_ctx.N = BN_dup(GN->N);
|
||||
s->srp_ctx.g = BN_dup(GN->g);
|
||||
if(s->srp_ctx.v != NULL)
|
||||
{
|
||||
BN_clear_free(s->srp_ctx.v);
|
||||
s->srp_ctx.v = NULL;
|
||||
}
|
||||
if(s->srp_ctx.s != NULL)
|
||||
{
|
||||
BN_clear_free(s->srp_ctx.s);
|
||||
s->srp_ctx.s = NULL;
|
||||
}
|
||||
if(!SRP_create_verifier_BN(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
|
||||
BIGNUM *sa, BIGNUM *v, char *info)
|
||||
{
|
||||
if (N!= NULL)
|
||||
{
|
||||
if (s->srp_ctx.N != NULL)
|
||||
{
|
||||
if (!BN_copy(s->srp_ctx.N,N))
|
||||
{
|
||||
BN_free(s->srp_ctx.N);
|
||||
s->srp_ctx.N = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->srp_ctx.N = BN_dup(N);
|
||||
}
|
||||
if (g!= NULL)
|
||||
{
|
||||
if (s->srp_ctx.g != NULL)
|
||||
{
|
||||
if (!BN_copy(s->srp_ctx.g,g))
|
||||
{
|
||||
BN_free(s->srp_ctx.g);
|
||||
s->srp_ctx.g = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->srp_ctx.g = BN_dup(g);
|
||||
}
|
||||
if (sa!= NULL)
|
||||
{
|
||||
if (s->srp_ctx.s != NULL)
|
||||
{
|
||||
if (!BN_copy(s->srp_ctx.s,sa))
|
||||
{
|
||||
BN_free(s->srp_ctx.s);
|
||||
s->srp_ctx.s = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->srp_ctx.s = BN_dup(sa);
|
||||
}
|
||||
if (v!= NULL)
|
||||
{
|
||||
if (s->srp_ctx.v != NULL)
|
||||
{
|
||||
if (!BN_copy(s->srp_ctx.v,v))
|
||||
{
|
||||
BN_free(s->srp_ctx.v);
|
||||
s->srp_ctx.v = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->srp_ctx.v = BN_dup(v);
|
||||
}
|
||||
s->srp_ctx.info = info;
|
||||
|
||||
if (!(s->srp_ctx.N) ||
|
||||
!(s->srp_ctx.g) ||
|
||||
!(s->srp_ctx.s) ||
|
||||
!(s->srp_ctx.v))
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key)
|
||||
{
|
||||
BIGNUM *K = NULL, *u = NULL;
|
||||
int ret = -1, tmp_len;
|
||||
unsigned char *tmp = NULL;
|
||||
|
||||
if (!SRP_Verify_A_mod_N(s->srp_ctx.A,s->srp_ctx.N))
|
||||
goto err;
|
||||
if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N)))
|
||||
goto err;
|
||||
if (!(K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)))
|
||||
goto err;
|
||||
|
||||
tmp_len = BN_num_bytes(K);
|
||||
if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
|
||||
goto err;
|
||||
BN_bn2bin(K, tmp);
|
||||
ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
|
||||
err:
|
||||
if (tmp)
|
||||
{
|
||||
OPENSSL_cleanse(tmp,tmp_len) ;
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
BN_clear_free(K);
|
||||
BN_clear_free(u);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* client side */
|
||||
int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key)
|
||||
{
|
||||
BIGNUM *x = NULL, *u = NULL, *K = NULL;
|
||||
int ret = -1, tmp_len;
|
||||
char *passwd = NULL;
|
||||
unsigned char *tmp = NULL;
|
||||
|
||||
/* Checks if b % n == 0
|
||||
*/
|
||||
if (SRP_Verify_B_mod_N(s->srp_ctx.B,s->srp_ctx.N)==0) goto err;
|
||||
if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) goto err;
|
||||
if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) goto err;
|
||||
if (!(passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg))) goto err;
|
||||
if (!(x = SRP_Calc_x(s->srp_ctx.s,s->srp_ctx.login,passwd))) goto err;
|
||||
if (!(K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, s->srp_ctx.a, u))) goto err;
|
||||
|
||||
tmp_len = BN_num_bytes(K);
|
||||
if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) goto err;
|
||||
BN_bn2bin(K, tmp);
|
||||
ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
|
||||
err:
|
||||
if (tmp)
|
||||
{
|
||||
OPENSSL_cleanse(tmp,tmp_len) ;
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
BN_clear_free(K);
|
||||
BN_clear_free(x);
|
||||
if (passwd)
|
||||
{
|
||||
OPENSSL_cleanse(passwd,strlen(passwd)) ;
|
||||
OPENSSL_free(passwd);
|
||||
}
|
||||
BN_clear_free(u);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SRP_Calc_A_param(SSL *s)
|
||||
{
|
||||
unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
|
||||
|
||||
if (BN_num_bits(s->srp_ctx.N) < s->srp_ctx.strength)
|
||||
return -1;
|
||||
|
||||
if (s->srp_ctx.SRP_verify_param_callback ==NULL &&
|
||||
!SRP_check_known_gN_param(s->srp_ctx.g,s->srp_ctx.N))
|
||||
return -1 ;
|
||||
|
||||
RAND_bytes(rnd, sizeof(rnd));
|
||||
s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
|
||||
OPENSSL_cleanse(rnd, sizeof(rnd));
|
||||
|
||||
if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a,s->srp_ctx.N,s->srp_ctx.g)))
|
||||
return -1;
|
||||
|
||||
/* We can have a callback to verify SRP param!! */
|
||||
if (s->srp_ctx.SRP_verify_param_callback !=NULL)
|
||||
return s->srp_ctx.SRP_verify_param_callback(s,s->srp_ctx.SRP_cb_arg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SRP_have_to_put_srp_username(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback == NULL)
|
||||
return 0;
|
||||
if ((s->srp_ctx.login = s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback(s,s->srp_ctx.SRP_cb_arg)) == NULL)
|
||||
return 0;
|
||||
s->srp_ctx.srp_Mask|=SSL_kSRP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIGNUM *SSL_get_srp_g(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.g != NULL)
|
||||
return s->srp_ctx.g;
|
||||
return s->ctx->srp_ctx.g;
|
||||
}
|
||||
|
||||
BIGNUM *SSL_get_srp_N(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.N != NULL)
|
||||
return s->srp_ctx.N;
|
||||
return s->ctx->srp_ctx.N;
|
||||
}
|
||||
|
||||
char *SSL_get_srp_username(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.login != NULL)
|
||||
return s->srp_ctx.login;
|
||||
return s->ctx->srp_ctx.login;
|
||||
}
|
||||
|
||||
char *SSL_get_srp_userinfo(SSL *s)
|
||||
{
|
||||
if (s->srp_ctx.info != NULL)
|
||||
return s->srp_ctx.info;
|
||||
return s->ctx->srp_ctx.info;
|
||||
}
|
||||
|
||||
#define tls1_ctx_ctrl ssl3_ctx_ctrl
|
||||
#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
|
||||
|
||||
int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name)
|
||||
{
|
||||
return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password)
|
||||
{
|
||||
return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
|
||||
{
|
||||
return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *))
|
||||
{
|
||||
return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
|
||||
(void (*)())cb);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
|
||||
{
|
||||
return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_SRP_ARG,0,arg);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
|
||||
int (*cb)(SSL *,int *,void *))
|
||||
{
|
||||
return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
|
||||
(void (*)())cb);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *))
|
||||
{
|
||||
return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
|
||||
(void (*)())cb);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx,
|
||||
char *(*cb)(SSL *,void *))
|
||||
{
|
||||
return tls1_ctx_callback_ctrl(ctx,
|
||||
SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB,
|
||||
(void (*)())cb);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user